From ae74579ea58e466c6e61066e974c484b4da08e26 Mon Sep 17 00:00:00 2001 From: richardbarry Date: Wed, 20 Apr 2011 15:09:58 +0000 Subject: [PATCH] Create directory structure to hold the (not yet created) Keil and IAR demo projects for the SmartFusion. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1370 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- .../FreeRTOSConfig.h | 168 + .../MicroSemi_Code/CMSIS/a2fxxxm3.h | 1102 +++++ .../MicroSemi_Code/CMSIS/core_cm3.c | 784 ++++ .../MicroSemi_Code/CMSIS/core_cm3.h | 1818 ++++++++ .../MicroSemi_Code/CMSIS/mss_assert.h | 48 + .../debug-in-actel-smartfusion-envm.ld | 184 + .../debug-in-actel-smartfusion-esram.ld | 177 + .../startup_gcc/debug-in-external-ram.ld | 185 + .../CMSIS/startup_gcc/newlib_stubs.c | 247 ++ .../production-execute-in-place.ld | 172 + .../production-relocate-executable.ld | 176 + .../CMSIS/startup_gcc/startup_a2fxxxm3.s | 1504 +++++++ .../MicroSemi_Code/CMSIS/system_a2fxxxm3.c | 199 + .../MicroSemi_Code/CMSIS/system_a2fxxxm3.h | 49 + .../MicroSemi_Code/drivers/I2C/i2c.c | 798 ++++ .../MicroSemi_Code/drivers/I2C/i2c.h | 775 ++++ .../MicroSemi_Code/drivers/OLED/oled.c | 536 +++ .../MicroSemi_Code/drivers/OLED/oled.h | 210 + .../MicroSemi_Code/drivers/bsp_config.h | 28 + .../drivers/mss_ace/ace_convert.c | 831 ++++ .../drivers/mss_ace/ace_flags.c | 1678 +++++++ .../MicroSemi_Code/drivers/mss_ace/ace_sse.c | 306 ++ .../drivers/mss_ace/ace_transform.c | 467 ++ .../drivers/mss_ace/envm_layout.h | 37 + .../MicroSemi_Code/drivers/mss_ace/mss_ace.c | 744 ++++ .../MicroSemi_Code/drivers/mss_ace/mss_ace.h | 2816 ++++++++++++ .../drivers/mss_ace/mss_ace_configurator.h | 622 +++ .../MicroSemi_Code/drivers/mss_ace/mtd_data.h | 104 + .../drivers/mss_ethernet_mac/crc32.c | 103 + .../drivers/mss_ethernet_mac/crc32.h | 46 + .../mss_ethernet_mac/mss_ethernet_mac.c | 1543 +++++++ .../mss_ethernet_mac/mss_ethernet_mac.h | 585 +++ .../mss_ethernet_mac/mss_ethernet_mac_conf.h | 43 + .../mss_ethernet_mac/mss_ethernet_mac_desc.h | 346 ++ .../mss_ethernet_mac/mss_ethernet_mac_regs.h | 1201 +++++ .../mss_ethernet_mac_user_cfg.h | 26 + .../drivers/mss_ethernet_mac/phy.c | 390 ++ .../drivers/mss_ethernet_mac/phy.h | 78 + .../drivers/mss_gpio/mss_gpio.c | 283 ++ .../drivers/mss_gpio/mss_gpio.h | 488 +++ .../drivers/mss_pdma/mss_pdma.c | 413 ++ .../drivers/mss_pdma/mss_pdma.h | 703 +++ .../MicroSemi_Code/drivers/mss_spi/mss_spi.c | 610 +++ .../MicroSemi_Code/drivers/mss_spi/mss_spi.h | 1296 ++++++ .../drivers/mss_uart/mss_uart.c | 458 ++ .../drivers/mss_uart/mss_uart.h | 626 +++ .../drivers/mss_watchdog/mss_watchdog.h | 427 ++ Demo/CORTEX_A2F200_IAR_and_Keil/ParTest.c | 179 + .../WebServer/httpd-cgi.c | 277 ++ .../WebServer/httpd-fs/404.html | 8 + .../WebServer/httpd-fs/index.html | 13 + .../WebServer/httpd-fs/index.shtml | 20 + .../WebServer/httpd-fs/io.shtml | 28 + .../WebServer/httpd-fs/logo.jpg | Bin 0 -> 32592 bytes .../WebServer/httpd-fs/runtime.shtml | 20 + .../WebServer/httpd-fs/stats.shtml | 47 + .../WebServer/httpd-fs/tcp.shtml | 21 + .../WebServer/httpd-fsdata.c | 3871 +++++++++++++++++ .../WebServer/makefsdata | 79 + .../WebServer/uip-conf.h | 161 + .../WebServer/webserver.h | 47 + Demo/CORTEX_A2F200_IAR_and_Keil/main-blinky.c | 378 ++ Demo/CORTEX_A2F200_IAR_and_Keil/main-full.c | 618 +++ .../printf-stdarg.c | 293 ++ Demo/CORTEX_A2F200_IAR_and_Keil/uIP_Task.c | 449 ++ 65 files changed, 32939 insertions(+) create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/FreeRTOSConfig.h create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/a2fxxxm3.h create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/core_cm3.c create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/core_cm3.h create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/mss_assert.h create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/debug-in-actel-smartfusion-envm.ld create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/debug-in-actel-smartfusion-esram.ld create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/debug-in-external-ram.ld create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/newlib_stubs.c create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/production-execute-in-place.ld create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/production-relocate-executable.ld create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/startup_a2fxxxm3.s create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/system_a2fxxxm3.c create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/system_a2fxxxm3.h create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/I2C/i2c.c create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/I2C/i2c.h create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/OLED/oled.c create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/OLED/oled.h create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/bsp_config.h create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/ace_convert.c create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/ace_flags.c create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/ace_sse.c create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/ace_transform.c create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/envm_layout.h create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/mss_ace.c create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/mss_ace.h create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/mss_ace_configurator.h create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/mtd_data.h create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/crc32.c create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/crc32.h create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac.c create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac.h create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_conf.h create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_desc.h create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_regs.h create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_user_cfg.h create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/phy.c create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/phy.h create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_gpio/mss_gpio.c create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_gpio/mss_gpio.h create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_pdma/mss_pdma.c create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_pdma/mss_pdma.h create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_spi/mss_spi.c create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_spi/mss_spi.h create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_uart/mss_uart.c create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_uart/mss_uart.h create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_watchdog/mss_watchdog.h create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/ParTest.c create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-cgi.c create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-fs/404.html create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-fs/index.html create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-fs/index.shtml create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-fs/io.shtml create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-fs/logo.jpg create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-fs/runtime.shtml create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-fs/stats.shtml create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-fs/tcp.shtml create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-fsdata.c create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/makefsdata create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/uip-conf.h create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/webserver.h create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/main-blinky.c create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/main-full.c create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/printf-stdarg.c create mode 100644 Demo/CORTEX_A2F200_IAR_and_Keil/uIP_Task.c diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/FreeRTOSConfig.h b/Demo/CORTEX_A2F200_IAR_and_Keil/FreeRTOSConfig.h new file mode 100644 index 000000000..fc0d7cd2f --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/FreeRTOSConfig.h @@ -0,0 +1,168 @@ +/* + FreeRTOS V7.0.0 - Copyright (C) 2011 Real Time Engineers Ltd. + + + FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by: + Atollic AB - Atollic provides professional embedded systems development + tools for C/C++ development, code analysis and test automation. + See http://www.atollic.com + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and 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 modification 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 ) 90 ) +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 40 * 1024 ) ) +#define configMAX_TASK_NAME_LEN ( 10 ) +#define configUSE_TRACE_FACILITY 1 +#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 1 +#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 10 +#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 ) + +/* 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 5 /* 15 priority levels */ +#endif + +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0x1f +#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 + +/* MAC address configuration. */ +#define configMAC_ADDR0 0x00 +#define configMAC_ADDR1 0x12 +#define configMAC_ADDR2 0x13 +#define configMAC_ADDR3 0x10 +#define configMAC_ADDR4 0x15 +#define configMAC_ADDR5 0x11 + +/* IP address configuration. */ +#define configIP_ADDR0 192 +#define configIP_ADDR1 168 +#define configIP_ADDR2 0 +#define configIP_ADDR3 200 + +/* Netmask configuration. */ +#define configNET_MASK0 255 +#define configNET_MASK1 255 +#define configNET_MASK2 255 +#define configNET_MASK3 0 + +#endif /* FREERTOS_CONFIG_H */ + diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/a2fxxxm3.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/a2fxxxm3.h new file mode 100644 index 000000000..ab389e05d --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/a2fxxxm3.h @@ -0,0 +1,1102 @@ +/******************************************************************************* + * (c) Copyright 2009 Actel Corporation. All rights reserved. + * + * SmartFusion A2FxxxM3 Cortex Microcontroller Software Interface - Peripheral + * Access Layer. + * + * This file describes the interrupt assignment and peripheral registers for + * the SmartFusion A2FxxxM3 familly of devices. + * + * SVN $Revision: 2331 $ + * SVN $Date: 2010-02-26 12:02:06 +0000 (Fri, 26 Feb 2010) $ + */ +#ifndef __A2FXXXM3_H__ +#define __A2FXXXM3_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * ========================================================================== + * ---------- Interrupt Number Definition ----------------------------------- + * ========================================================================== + */ + +typedef enum IRQn +{ +/****** Cortex-M3 Processor Exceptions Numbers *********************************************************/ + NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /*!< 2 Hard Fault Interrupt */ + MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 Memory Management Interrupt */ + BusFault_IRQn = -11, /*!< 5 Cortex-M3 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /*!< 6 Cortex-M3 Usage Fault Interrupt */ + SVCall_IRQn = -5, /*!< 11 Cortex-M3 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /*!< 14 Cortex-M3 Pend SV Interrupt */ + SysTick_IRQn = -1, /*!< 15 Cortex-M3 System Tick Interrupt */ + +/****** SmartFusion specific Interrupt Numbers *********************************************************/ + WdogWakeup_IRQn = 0, /*!< WatchDog wakeup interrupt */ + BrownOut_1_5V_IRQn = 1, /*!< Supply dropped below 1.5V */ + BrownOut_3_3V_IRQn = 2, /*!< Supply dropped below 1.5V */ + RTC_Match_IRQn = 3, /*!< RTC match interrupt */ + RTCIF_Pub_IRQn = 4, /*!< RTC interface push button interrupt */ + EthernetMAC_IRQn = 5, /*!< Ethernet MAC interrupt */ + IAP_IRQn = 6, /*!< In Application Programming (IAP) interrupt */ + ENVM0_IRQn = 7, /*!< eNVM0 operation completion interrupt */ + ENVM1_IRQn = 8, /*!< eNVM1 operation completion interrupt */ + DMA_IRQn = 9, /*!< Peripheral DMA interrupt */ + UART0_IRQn = 10, /*!< UART0 interrupt */ + UART1_IRQn = 11, /*!< UART1 interrupt */ + SPI0_IRQn = 12, /*!< SPI0 interrupt */ + SPI1_IRQn = 13, /*!< SP1 interrupt */ + I2C0_IRQn = 14, /*!< I2C0 interrupt */ + I2C0_SMBAlert_IRQn = 15, /*!< I2C0 SMBus Alert interrupt */ + I2C0_SMBus_IRQn = 16, /*!< I2C0 SMBus Suspend interrupt */ + I2C1_IRQn = 17, /*!< I2C1 interrupt */ + I2C1_SMBAlert_IRQn = 18, /*!< I2C1 SMBus Alert interrupt */ + I2C1_SMBus_IRQn = 19, /*!< I2C1 SMBus Suspend interrupt */ + Timer1_IRQn = 20, /*!< Timer1 interrupt */ + Timer2_IRQn = 21, /*!< Timer2 interrupt */ + PLL_Lock_IRQn = 22, /*!< PLL lock interrupt */ + PLL_LockLost_IRQn = 23, /*!< PLL loss of lock interrupt */ + CommError_IRQn = 24, /*!< Communications Matrix error interrupt */ + Fabric_IRQn = 31, /*!< FPGA fabric interrupt */ + GPIO0_IRQn = 32, /*!< GPIO 0 interrupt */ + GPIO1_IRQn = 33, /*!< GPIO 1 interrupt */ + GPIO2_IRQn = 34, /*!< GPIO 2 interrupt */ + GPIO3_IRQn = 35, /*!< GPIO 3 interrupt */ + GPIO4_IRQn = 36, /*!< GPIO 4 interrupt */ + GPIO5_IRQn = 37, /*!< GPIO 5 interrupt */ + GPIO6_IRQn = 38, /*!< GPIO 6 interrupt */ + GPIO7_IRQn = 39, /*!< GPIO 7 interrupt */ + GPIO8_IRQn = 40, /*!< GPIO 8 interrupt */ + GPIO9_IRQn = 41, /*!< GPIO 9 interrupt */ + GPIO10_IRQn = 42, /*!< GPIO 10 interrupt */ + GPIO11_IRQn = 43, /*!< GPIO 11 interrupt */ + GPIO12_IRQn = 44, /*!< GPIO 12 interrupt */ + GPIO13_IRQn = 45, /*!< GPIO 13 interrupt */ + GPIO14_IRQn = 46, /*!< GPIO 14 interrupt */ + GPIO15_IRQn = 47, /*!< GPIO 15 interrupt */ + GPIO16_IRQn = 48, /*!< GPIO 16 interrupt */ + GPIO17_IRQn = 49, /*!< GPIO 17 interrupt */ + GPIO18_IRQn = 50, /*!< GPIO 18 interrupt */ + GPIO19_IRQn = 51, /*!< GPIO 19 interrupt */ + GPIO20_IRQn = 52, /*!< GPIO 20 interrupt */ + GPIO21_IRQn = 53, /*!< GPIO 21 interrupt */ + GPIO22_IRQn = 54, /*!< GPIO 22 interrupt */ + GPIO23_IRQn = 55, /*!< GPIO 23 interrupt */ + GPIO24_IRQn = 56, /*!< GPIO 24 interrupt */ + GPIO25_IRQn = 57, /*!< GPIO 25 interrupt */ + GPIO26_IRQn = 58, /*!< GPIO 26 interrupt */ + GPIO27_IRQn = 59, /*!< GPIO 27 interrupt */ + GPIO28_IRQn = 60, /*!< GPIO 28 interrupt */ + GPIO29_IRQn = 61, /*!< GPIO 29 interrupt */ + GPIO30_IRQn = 62, /*!< GPIO 30 interrupt */ + GPIO31_IRQn = 63, /*!< GPIO 31 interrupt */ + ACE_PC0_Flag0_IRQn = 64, /*!< ACE SSE program counter 0 flag 0 interrupt */ + ACE_PC0_Flag1_IRQn = 65, /*!< ACE SSE program counter 0 flag 1 interrupt */ + ACE_PC0_Flag2_IRQn = 66, /*!< ACE SSE program counter 0 flag 2 interrupt */ + ACE_PC0_Flag3_IRQn = 67, /*!< ACE SSE program counter 0 flag 3 interrupt */ + ACE_PC1_Flag0_IRQn = 68, /*!< ACE SSE program counter 1 flag 0 interrupt */ + ACE_PC1_Flag1_IRQn = 69, /*!< ACE SSE program counter 1 flag 1 interrupt */ + ACE_PC1_Flag2_IRQn = 70, /*!< ACE SSE program counter 1 flag 2 interrupt */ + ACE_PC1_Flag3_IRQn = 71, /*!< ACE SSE program counter 1 flag 3 interrupt */ + ACE_PC2_Flag0_IRQn = 72, /*!< ACE SSE program counter 2 flag 0 interrupt */ + ACE_PC2_Flag1_IRQn = 73, /*!< ACE SSE program counter 2 flag 1 interrupt */ + ACE_PC2_Flag2_IRQn = 74, /*!< ACE SSE program counter 2 flag 2 interrupt */ + ACE_PC2_Flag3_IRQn = 75, /*!< ACE SSE program counter 2 flag 3 interrupt */ + ACE_ADC0_DataValid_IRQn = 76, /*!< ACE ADC0 data valid interrupt */ + ACE_ADC1_DataValid_IRQn = 77, /*!< ACE ADC1 data valid interrupt */ + ACE_ADC2_DataValid_IRQn = 78, /*!< ACE ADC2 data valid interrupt */ + ACE_ADC0_CalDone_IRQn = 79, /*!< ACE ADC0 calibration done interrupt */ + ACE_ADC1_CalDone_IRQn = 80, /*!< ACE ADC1 calibration done interrupt */ + ACE_ADC2_CalDone_IRQn = 81, /*!< ACE ADC2 calibration done interrupt */ + ACE_ADC0_CalStart_IRQn = 82, /*!< ACE ADC0 calibration start interrupt */ + ACE_ADC1_CalStart_IRQn = 83, /*!< ACE ADC1 calibration start interrupt */ + ACE_ADC2_CalStart_IRQn = 84, /*!< ACE ADC2 calibration start interrupt */ + ACE_Comp0_Fall_IRQn = 85, /*!< ACE comparator 0 falling under reference interrupt */ + ACE_Comp1_Fall_IRQn = 86, /*!< ACE comparator 1 falling under reference interrupt */ + ACE_Comp2_Fall_IRQn = 87, /*!< ACE comparator 2 falling under reference interrupt */ + ACE_Comp3_Fall_IRQn = 88, /*!< ACE comparator 3 falling under reference interrupt */ + ACE_Comp4_Fall_IRQn = 89, /*!< ACE comparator 4 falling under reference interrupt */ + ACE_Comp5_Fall_IRQn = 90, /*!< ACE comparator 5 falling under reference interrupt */ + ACE_Comp6_Fall_IRQn = 91, /*!< ACE comparator 6 falling under reference interrupt */ + ACE_Comp7_Fall_IRQn = 92, /*!< ACE comparator 7 falling under reference interrupt */ + ACE_Comp8_Fall_IRQn = 93, /*!< ACE comparator 8 falling under reference interrupt */ + ACE_Comp9_Fall_IRQn = 94, /*!< ACE comparator 9 falling under reference interrupt */ + ACE_Comp10_Fall_IRQn = 95, /*!< ACE comparator 10 falling under reference interrupt */ + ACE_Comp11_Fall_IRQn = 96, /*!< ACE comparator 11 falling under reference interrupt */ + ACE_Comp0_Rise_IRQn = 97, /*!< ACE comparator 0 rising over reference interrupt */ + ACE_Comp1_Rise_IRQn = 98, /*!< ACE comparator 1 rising over reference interrupt */ + ACE_Comp2_Rise_IRQn = 99, /*!< ACE comparator 2 rising over reference interrupt */ + ACE_Comp3_Rise_IRQn = 100, /*!< ACE comparator 3 rising over reference interrupt */ + ACE_Comp4_Rise_IRQn = 101, /*!< ACE comparator 4 rising over reference interrupt */ + ACE_Comp5_Rise_IRQn = 102, /*!< ACE comparator 5 rising over reference interrupt */ + ACE_Comp6_Rise_IRQn = 103, /*!< ACE comparator 6 rising over reference interrupt */ + ACE_Comp7_Rise_IRQn = 104, /*!< ACE comparator 7 rising over reference interrupt */ + ACE_Comp8_Rise_IRQn = 105, /*!< ACE comparator 8 rising over reference interrupt */ + ACE_Comp9_Rise_IRQn = 106, /*!< ACE comparator 9 rising over reference interrupt */ + ACE_Comp10_Rise_IRQn = 107, /*!< ACE comparator 10 rising over reference interrupt */ + ACE_Comp11_Rise_IRQn = 108, /*!< ACE comparator 11 rising over reference interrupt */ + ACE_ADC0_FifoFull_IRQn = 109, /*!< ACE ADC0 FIFO full interrupt */ + ACE_ADC0_FifoAFull_IRQn = 110, /*!< ACE ADC0 FIFO almost full interrupt */ + ACE_ADC0_FifoEmpty_IRQn = 111, /*!< ACE ADC0 FIFO empty interrupt */ + ACE_ADC1_FifoFull_IRQn = 112, /*!< ACE ADC1 FIFO full interrupt */ + ACE_ADC1_FifoAFull_IRQn = 113, /*!< ACE ADC1 FIFO almost full interrupt */ + ACE_ADC1_FifoEmpty_IRQn = 114, /*!< ACE ADC1 FIFO empty interrupt */ + ACE_ADC2_FifoFull_IRQn = 115, /*!< ACE ADC2 FIFO full interrupt */ + ACE_ADC2_FifoAFull_IRQn = 116, /*!< ACE ADC2 FIFO almost full interrupt */ + ACE_ADC2_FifoEmpty_IRQn = 117, /*!< ACE ADC2 FIFO empty interrupt */ + ACE_PPE_Flag0_IRQn = 118, /*!< ACE post processing engine flag 0 interrupt */ + ACE_PPE_Flag1_IRQn = 119, /*!< ACE post processing engine flag 1 interrupt */ + ACE_PPE_Flag2_IRQn = 120, /*!< ACE post processing engine flag 2 interrupt */ + ACE_PPE_Flag3_IRQn = 121, /*!< ACE post processing engine flag 3 interrupt */ + ACE_PPE_Flag4_IRQn = 122, /*!< ACE post processing engine flag 4 interrupt */ + ACE_PPE_Flag5_IRQn = 123, /*!< ACE post processing engine flag 5 interrupt */ + ACE_PPE_Flag6_IRQn = 124, /*!< ACE post processing engine flag 6 interrupt */ + ACE_PPE_Flag7_IRQn = 125, /*!< ACE post processing engine flag 7 interrupt */ + ACE_PPE_Flag8_IRQn = 126, /*!< ACE post processing engine flag 8 interrupt */ + ACE_PPE_Flag9_IRQn = 127, /*!< ACE post processing engine flag 9 interrupt */ + ACE_PPE_Flag10_IRQn = 128, /*!< ACE post processing engine flag 10 interrupt */ + ACE_PPE_Flag11_IRQn = 129, /*!< ACE post processing engine flag 11 interrupt */ + ACE_PPE_Flag12_IRQn = 130, /*!< ACE post processing engine flag 12 interrupt */ + ACE_PPE_Flag13_IRQn = 131, /*!< ACE post processing engine flag 13 interrupt */ + ACE_PPE_Flag14_IRQn = 132, /*!< ACE post processing engine flag 14 interrupt */ + ACE_PPE_Flag15_IRQn = 133, /*!< ACE post processing engine flag 15 interrupt */ + ACE_PPE_Flag16_IRQn = 134, /*!< ACE post processing engine flag 16 interrupt */ + ACE_PPE_Flag17_IRQn = 135, /*!< ACE post processing engine flag 17 interrupt */ + ACE_PPE_Flag18_IRQn = 136, /*!< ACE post processing engine flag 18 interrupt */ + ACE_PPE_Flag19_IRQn = 137, /*!< ACE post processing engine flag 19 interrupt */ + ACE_PPE_Flag20_IRQn = 138, /*!< ACE post processing engine flag 20 interrupt */ + ACE_PPE_Flag21_IRQn = 139, /*!< ACE post processing engine flag 21 interrupt */ + ACE_PPE_Flag22_IRQn = 140, /*!< ACE post processing engine flag 22 interrupt */ + ACE_PPE_Flag23_IRQn = 141, /*!< ACE post processing engine flag 23 interrupt */ + ACE_PPE_Flag24_IRQn = 142, /*!< ACE post processing engine flag 24 interrupt */ + ACE_PPE_Flag25_IRQn = 143, /*!< ACE post processing engine flag 25 interrupt */ + ACE_PPE_Flag26_IRQn = 144, /*!< ACE post processing engine flag 26 interrupt */ + ACE_PPE_Flag27_IRQn = 145, /*!< ACE post processing engine flag 27 interrupt */ + ACE_PPE_Flag28_IRQn = 146, /*!< ACE post processing engine flag 28 interrupt */ + ACE_PPE_Flag29_IRQn = 147, /*!< ACE post processing engine flag 29 interrupt */ + ACE_PPE_Flag30_IRQn = 148, /*!< ACE post processing engine flag 30 interrupt */ + ACE_PPE_Flag31_IRQn = 149 /*!< ACE post processing engine flag 31 interrupt */ +} IRQn_Type; + + +/* + * ========================================================================== + * ----------- Processor and Core Peripheral Section ------------------------ + * ========================================================================== + */ + +/* Configuration of the Cortex-M3 Processor and Core Peripherals */ +#define __MPU_PRESENT 1 /*!< SmartFusion includes a MPU */ +#define __NVIC_PRIO_BITS 5 /*!< SmartFusion uses 5 Bits for the Priority Levels */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ + + +#include "core_cm3.h" /* Cortex-M3 processor and core peripherals */ +#include "system_a2fxxxm3.h" /* SmartFusion System */ + +/******************************************************************************/ +/* Device Specific Peripheral registers structures */ +/******************************************************************************/ +#if defined ( __CC_ARM ) + /* Enable anonymous unions when building using Keil-MDK */ + #pragma anon_unions +#endif +/*----------------------------------------------------------------------------*/ +/*----------------------------------- UART -----------------------------------*/ +/*----------------------------------------------------------------------------*/ +typedef struct +{ + union + { + __I uint8_t RBR; + __O uint8_t THR; + __IO uint8_t DLR; + uint32_t RESERVED0; + }; + + union + { + __IO uint8_t DMR; + __IO uint8_t IER; + uint32_t RESERVED1; + }; + + union + { + __IO uint8_t IIR; + __IO uint8_t FCR; + uint32_t RESERVED2; + }; + + __IO uint8_t LCR; + uint8_t RESERVED3; + uint16_t RESERVED4; + __IO uint8_t MCR; + uint8_t RESERVED5; + uint16_t RESERVED6; + __I uint8_t LSR; + uint8_t RESERVED7; + uint16_t RESERVED8; + __I uint8_t MSR; + uint8_t RESERVED9; + uint16_t RESERVED10; + __IO uint8_t SR; + uint8_t RESERVED11; + uint16_t RESERVED12; +} UART_TypeDef; + +/*------------------------------------------------------------------------------ + * + */ +typedef struct +{ + uint32_t RESERVED0[32]; + + __IO uint32_t IER_ERBFI; + __IO uint32_t IER_ETBEI; + __IO uint32_t IER_ELSI; + __IO uint32_t IER_EDSSI; + + uint32_t RESERVED1[28]; + + __IO uint32_t FCR_ENABLE; + __IO uint32_t FCR_CLEAR_RX_FIFO; + __IO uint32_t FCR_CLEAR_TX_FIFO; + __IO uint32_t FCR_RXRDY_TXRDYN_EN; + __IO uint32_t FCR_RESERVED0; + __IO uint32_t FCR_RESERVED1; + __IO uint32_t FCR_RX_TRIG0; + __IO uint32_t FCR_RX_TRIG1; + + uint32_t RESERVED2[24]; + + __IO uint32_t LCR_WLS0; + __IO uint32_t LCR_WLS1; + __IO uint32_t LCR_STB; + __IO uint32_t LCR_PEN; + __IO uint32_t LCR_EPS; + __IO uint32_t LCR_SP; + __IO uint32_t LCR_SB; + __IO uint32_t LCR_DLAB; + + uint32_t RESERVED3[24]; + + __IO uint32_t MCR_DTR; + __IO uint32_t MCR_RTS; + __IO uint32_t MCR_OUT1; + __IO uint32_t MCR_OUT2; + __IO uint32_t MCR_LOOP; + + uint32_t RESERVED4[27]; + + __I uint32_t LSR_DR; + __I uint32_t LSR_OE; + __I uint32_t LSR_PE; + __I uint32_t LSR_FE; + __I uint32_t LSR_BI; + __I uint32_t LSR_THRE; + __I uint32_t LSR_TEMT; + __I uint32_t LSR_FIER; + + uint32_t RESERVED5[24]; + + __I uint32_t MSR_DCTS; + __I uint32_t MSR_DDSR; + __I uint32_t MSR_TERI; + __I uint32_t MSR_DDCD; + __I uint32_t MSR_CTS; + __I uint32_t MSR_DSR; + __I uint32_t MSR_RI; + __I uint32_t MSR_DCD; + +} UART_BitBand_TypeDef; + +/*----------------------------------------------------------------------------*/ +/*----------------------------------- I2C ------------------------------------*/ +/*----------------------------------------------------------------------------*/ +typedef struct +{ + __IO uint8_t CTRL; + uint8_t RESERVED0; + uint16_t RESERVED1; + uint8_t STATUS; + uint8_t RESERVED2; + uint16_t RESERVED3; + __IO uint8_t DATA; + uint8_t RESERVED4; + uint16_t RESERVED5; + __IO uint8_t ADDR; + uint8_t RESERVED6; + uint16_t RESERVED7; + __IO uint8_t SMBUS; + uint8_t RESERVED8; + uint16_t RESERVED9; + __IO uint8_t FREQ; + uint8_t RESERVED10; + uint16_t RESERVED11; + __IO uint8_t GLITCHREG; + uint8_t RESERVED12; + uint16_t RESERVED13; +} I2C_TypeDef; + +/*------------------------------------------------------------------------------ + * + */ +typedef struct +{ + uint32_t CTRL_CR0; + uint32_t CTRL_CR1; + uint32_t CTRL_AA; + uint32_t CTRL_SI; + uint32_t CTRL_STO; + uint32_t CTRL_STA; + uint32_t CTRL_ENS1; + uint32_t CTRL_CR2; + uint32_t RESERVED0[56]; + uint32_t DATA_DIR; + uint32_t RESERVED1[31]; + uint32_t ADDR_GC; +} I2C_BitBand_TypeDef; + +/*----------------------------------------------------------------------------*/ +/*----------------------------------- SPI ------------------------------------*/ +/*----------------------------------------------------------------------------*/ +typedef struct +{ + __IO uint32_t CONTROL; + __IO uint32_t TXRXDF_SIZE; + __I uint32_t STATUS; + __O uint32_t INT_CLEAR; + __I uint32_t RX_DATA; + __O uint32_t TX_DATA; + __IO uint32_t CLK_GEN; + __IO uint32_t SLAVE_SELECT; + __I uint32_t MIS; + __I uint32_t RIS; +} SPI_TypeDef; + +typedef struct +{ + __IO uint32_t CTRL_ENABLE; + __IO uint32_t CTRL_MASTER; + __IO uint32_t CTRL_MODE[2]; + __IO uint32_t CTRL_RX_INT_EN; + __IO uint32_t CTRL_TX_INT_EN; + __IO uint32_t CTRL_RX_OVERFLOW_INT_EN; + __IO uint32_t CTRL_TX_UNDERRUN_INT_EN; + __IO uint32_t CTRL_TXRXDFCOUNT[16]; + __IO uint32_t CTRL_SPO; + __IO uint32_t CTRL_SPH; + __IO uint32_t CTRL_RESERVED[6]; + + __IO uint32_t TXRXDF_SIZE[32]; + + __I uint32_t STATUS_TX_DONE; + __I uint32_t STATUS_RX_RDY; + __I uint32_t STATUS_RX_CH_OV; + __I uint32_t STATUS_TX_CH_UV; + __I uint32_t STATUS_RX_FIFO_FULL; + __I uint32_t STATUS_RX_FIFO_FULL_NEXT; + __I uint32_t STATUS_RX_FIFO_EMPTY; + __I uint32_t STATUS_RX_FIFO_EMPTY_NEXT; + __I uint32_t STATUS_TX_FIFO_FULL; + __I uint32_t STATUS_TX_FIFO_FULL_NEXT; + __I uint32_t STATUS_TX_FIFO_EMPTY; + __I uint32_t STATUS_TX_FIFO_EMPTY_NEXT; + __I uint32_t STATUS_RESERVED[20]; + + __O uint32_t INT_CLEAR_TX_DONE; + __O uint32_t INT_CLEAR_RX_RDY; + __O uint32_t INT_CLEAR_RX_OVER; + __O uint32_t INT_CLEAR_TX_UNDER; + __O uint32_t INT_CLEAR[28]; + + __I uint32_t RX_DATA[32]; + __O uint32_t TX_DATA[32]; + __IO uint32_t CLK_GEN[32]; + __IO uint32_t SLAVE_SELECT[32]; + __I uint32_t MIS_TX_DONE; + __I uint32_t MIS_RX_RDY; + __I uint32_t MIS_RX_OVER; + __I uint32_t MIS_TX_UNDER; + __I uint32_t MIS[28]; + __I uint32_t RIS[32]; +} SPI_BitBand_TypeDef; + +/*----------------------------------------------------------------------------*/ +/*----------------------------------- GPIO -----------------------------------*/ +/*----------------------------------------------------------------------------*/ +typedef struct +{ + __IO uint32_t GPIO_0_CFG; + __IO uint32_t GPIO_1_CFG; + __IO uint32_t GPIO_2_CFG; + __IO uint32_t GPIO_3_CFG; + __IO uint32_t GPIO_4_CFG; + __IO uint32_t GPIO_5_CFG; + __IO uint32_t GPIO_6_CFG; + __IO uint32_t GPIO_7_CFG; + __IO uint32_t GPIO_8_CFG; + __IO uint32_t GPIO_9_CFG; + __IO uint32_t GPIO_10_CFG; + __IO uint32_t GPIO_11_CFG; + __IO uint32_t GPIO_12_CFG; + __IO uint32_t GPIO_13_CFG; + __IO uint32_t GPIO_14_CFG; + __IO uint32_t GPIO_15_CFG; + __IO uint32_t GPIO_16_CFG; + __IO uint32_t GPIO_17_CFG; + __IO uint32_t GPIO_18_CFG; + __IO uint32_t GPIO_19_CFG; + __IO uint32_t GPIO_20_CFG; + __IO uint32_t GPIO_21_CFG; + __IO uint32_t GPIO_22_CFG; + __IO uint32_t GPIO_23_CFG; + __IO uint32_t GPIO_24_CFG; + __IO uint32_t GPIO_25_CFG; + __IO uint32_t GPIO_26_CFG; + __IO uint32_t GPIO_27_CFG; + __IO uint32_t GPIO_28_CFG; + __IO uint32_t GPIO_29_CFG; + __IO uint32_t GPIO_30_CFG; + __IO uint32_t GPIO_31_CFG; + __IO uint32_t GPIO_IRQ; + __I uint32_t GPIO_IN; + __IO uint32_t GPIO_OUT; +} GPIO_TypeDef; + +typedef struct +{ + __IO uint32_t GPIO_0_CFG[32]; + __IO uint32_t GPIO_1_CFG[32]; + __IO uint32_t GPIO_2_CFG[32]; + __IO uint32_t GPIO_3_CFG[32]; + __IO uint32_t GPIO_4_CFG[32]; + __IO uint32_t GPIO_5_CFG[32]; + __IO uint32_t GPIO_6_CFG[32]; + __IO uint32_t GPIO_7_CFG[32]; + __IO uint32_t GPIO_8_CFG[32]; + __IO uint32_t GPIO_9_CFG[32]; + __IO uint32_t GPIO_10_CFG[32]; + __IO uint32_t GPIO_11_CFG[32]; + __IO uint32_t GPIO_12_CFG[32]; + __IO uint32_t GPIO_13_CFG[32]; + __IO uint32_t GPIO_14_CFG[32]; + __IO uint32_t GPIO_15_CFG[32]; + __IO uint32_t GPIO_16_CFG[32]; + __IO uint32_t GPIO_17_CFG[32]; + __IO uint32_t GPIO_18_CFG[32]; + __IO uint32_t GPIO_19_CFG[32]; + __IO uint32_t GPIO_20_CFG[32]; + __IO uint32_t GPIO_21_CFG[32]; + __IO uint32_t GPIO_22_CFG[32]; + __IO uint32_t GPIO_23_CFG[32]; + __IO uint32_t GPIO_24_CFG[32]; + __IO uint32_t GPIO_25_CFG[32]; + __IO uint32_t GPIO_26_CFG[32]; + __IO uint32_t GPIO_27_CFG[32]; + __IO uint32_t GPIO_28_CFG[32]; + __IO uint32_t GPIO_29_CFG[32]; + __IO uint32_t GPIO_30_CFG[32]; + __IO uint32_t GPIO_31_CFG[32]; + __IO uint32_t GPIO_IRQ[32]; + __I uint32_t GPIO_IN[32]; + __IO uint32_t GPIO_OUT[32]; +} GPIO_BitBand_TypeDef; + + +/*----------------------------------------------------------------------------*/ +/*----------------------------------- RTC ------------------------------------*/ +/*----------------------------------------------------------------------------*/ +typedef struct +{ + __IO uint32_t COUNTER0_REG; + __IO uint32_t COUNTER1_REG; + __IO uint32_t COUNTER2_REG; + __IO uint32_t COUNTER3_REG; + __IO uint32_t COUNTER4_REG; + + __IO uint32_t RESERVED0[3]; + + __IO uint32_t MATCHREG0_REG; + __IO uint32_t MATCHREG1_REG; + __IO uint32_t MATCHREG2_REG; + __IO uint32_t MATCHREG3_REG; + __IO uint32_t MATCHREG4_REG; + + __IO uint32_t RESERVED1[3]; + + __IO uint32_t MATCHBITS0_REG; + __IO uint32_t MATCHBITS1_REG; + __IO uint32_t MATCHBITS2_REG; + __IO uint32_t MATCHBITS3_REG; + __IO uint32_t MATCHBITS4_REG; + + __IO uint32_t RESERVED2[3]; + + __IO uint32_t CTRL_STAT_REG; +} RTC_TypeDef; + +/*----------------------------------------------------------------------------*/ +/*---------------------------------- Timer -----------------------------------*/ +/*----------------------------------------------------------------------------*/ +typedef struct +{ + __I uint32_t TIM1_VAL; + __IO uint32_t TIM1_LOADVAL; + __IO uint32_t TIM1_BGLOADVAL; + __IO uint32_t TIM1_CTRL; + __IO uint32_t TIM1_RIS; + __I uint32_t TIM1_MIS; + + __I uint32_t TIM2_VAL; + __IO uint32_t TIM2_LOADVAL; + __IO uint32_t TIM2_BGLOADVAL; + __IO uint32_t TIM2_CTRL; + __IO uint32_t TIM2_RIS; + __I uint32_t TIM2_MIS; + + __I uint32_t TIM64_VAL_U; + __I uint32_t TIM64_VAL_L; + __IO uint32_t TIM64_LOADVAL_U; + __IO uint32_t TIM64_LOADVAL_L; + __IO uint32_t TIM64_BGLOADVAL_U; + __IO uint32_t TIM64_BGLOADVAL_L; + __IO uint32_t TIM64_CTRL; + __IO uint32_t TIM64_RIS; + __I uint32_t TIM64_MIS; + __IO uint32_t TIM64_MODE; +} TIMER_TypeDef; + +/*------------------------------------------------------------------------------ + * Timer bit band + */ +typedef struct +{ + __I uint32_t TIM1_VALUE_BIT[32]; + __IO uint32_t TIM1_LOADVAL[32]; + __IO uint32_t TIM1_BGLOADVAL[32]; + + __IO uint32_t TIM1ENABLE; + __IO uint32_t TIM1MODE; + __IO uint32_t TIM1INTEN; + __IO uint32_t TIM1_CTRL_RESERVED[29]; + __IO uint32_t TIM1_RIS[32]; + __I uint32_t TIM1_MIS[32]; + + __I uint32_t TIM2_VALUE[32]; + __IO uint32_t TIM2_LOADVAL[32]; + __IO uint32_t TIM2_BGLOADVAL[32]; + + __IO uint32_t TIM2ENABLE; + __IO uint32_t TIM2MODE; + __IO uint32_t TIM2INTEN; + __IO uint32_t TIM2_CTRL[29]; + __IO uint32_t TIM2_RIS[32]; + __I uint32_t TIM2_MIS[32]; + + __I uint32_t TIM64VALUEU[32]; + __I uint32_t TIM64VALUEL[32]; + __IO uint32_t TIM64LOADVALUEU[32]; + __IO uint32_t TIM64LOADVALUEL[32]; + __IO uint32_t TIM64BGLOADVALUEU[32]; + __IO uint32_t TIM64BGLOADVALUEL[32]; + __IO uint32_t TIM64ENABLE; + __IO uint32_t TIM64MODE; + __IO uint32_t TIM64INTEN; + __IO uint32_t TIM64_CTRL[29]; + __IO uint32_t TIM64_RIS[32]; + __I uint32_t TIM64_MIS[32]; + __IO uint32_t TIM64_MODE[32]; +} TIMER_BitBand_TypeDef; + +/*----------------------------------------------------------------------------*/ +/*--------------------------------- Watchdog ---------------------------------*/ +/*----------------------------------------------------------------------------*/ +typedef struct +{ + __I uint32_t WDOGVALUE; + __IO uint32_t WDOGLOAD; + __IO uint32_t WDOGMVRP; + __O uint32_t WDOGREFRESH; + __IO uint32_t WDOGENABLE; + __IO uint32_t WDOGCONTROL; + __I uint32_t WDOGSTATUS; + __IO uint32_t WDOGRIS; + __I uint32_t WDOGMIS; +} WATCHDOG_TypeDef; + +/*----------------------------------------------------------------------------*/ +/*----------------------------- Real Time Clock ------------------------------*/ +/*----------------------------------------------------------------------------*/ + +/*----------------------------------------------------------------------------*/ +/*----------------------------- Peripherals DMA ------------------------------*/ +/*----------------------------------------------------------------------------*/ +typedef struct +{ + __IO uint32_t CRTL; + __IO uint32_t STATUS; + __IO uint32_t BUFFER_A_SRC_ADDR; + __IO uint32_t BUFFER_A_DEST_ADDR; + __IO uint32_t BUFFER_A_TRANSFER_COUNT; + __IO uint32_t BUFFER_B_SRC_ADDR; + __IO uint32_t BUFFER_B_DEST_ADDR; + __IO uint32_t BUFFER_B_TRANSFER_COUNT; +} PDMA_Channel_TypeDef; + +typedef struct +{ + __IO uint32_t RATIO_HIGH_LOW; + __IO uint32_t BUFFER_STATUS; + uint32_t RESERVED[6]; + PDMA_Channel_TypeDef CHANNEL[8]; +} PDMA_TypeDef; + +/*----------------------------------------------------------------------------*/ +/*------------------------------ Ethernet MAC --------------------------------*/ +/*----------------------------------------------------------------------------*/ +typedef struct +{ + __IO uint32_t CSR0; + uint32_t RESERVED0; + __IO uint32_t CSR1; + uint32_t RESERVED1; + __IO uint32_t CSR2; + uint32_t RESERVED2; + __IO uint32_t CSR3; + uint32_t RESERVED3; + __IO uint32_t CSR4; + uint32_t RESERVED4; + __IO uint32_t CSR5; + uint32_t RESERVED5; + __IO uint32_t CSR6; + uint32_t RESERVED6; + __IO uint32_t CSR7; + uint32_t RESERVED7; + __IO uint32_t CSR8; + uint32_t RESERVED8; + __IO uint32_t CSR9; + uint32_t RESERVED9; + uint32_t RESERVED10; + uint32_t RESERVED11; + __IO uint32_t CSR11; +} MAC_TypeDef; + +/*----------------------------------------------------------------------------*/ +/*---------------------- Analog Conversion Engine (ACE) ----------------------*/ +/*----------------------------------------------------------------------------*/ +/* Analog quad configuration */ +typedef struct +{ + __IO uint8_t b0; + uint8_t reserved0_0; + uint16_t reserved0_1; + __IO uint8_t b1; + uint8_t reserved1_0; + uint16_t reserved1_1; + __IO uint8_t b2; + uint8_t reserved2_0; + uint16_t reserved2_1; + __IO uint8_t b3; + uint8_t reserved3_0; + uint16_t reserved3_1; + __IO uint8_t b4; + uint8_t reserved4_0; + uint16_t reserved4_1; + __IO uint8_t b5; + uint8_t reserved5_0; + uint16_t reserved5_1; + __IO uint8_t b6; + uint8_t reserved6_0; + uint16_t reserved6_1; + __IO uint8_t b7; + uint8_t reserved7_0; + uint16_t reserved7_1; + __IO uint8_t b8; + uint8_t reserved8_0; + uint16_t reserved8_1; + __IO uint8_t b9; + uint8_t reserved9_0; + uint16_t reserved9_1; + __IO uint8_t b10; + uint8_t reserved10_0; + uint16_t reserved10_1; + __IO uint8_t b11; + uint8_t reserved11_0; + uint16_t reserved11_1; +} AQ_config_t; + +/* ACE memory map layout */ +typedef struct +{ + __O uint32_t NOP; + __IO uint32_t SSE_TS_CTRL; + __IO uint32_t ADC_SYNC_CONV; + __IO uint32_t ANA_COMM_CTRL; + __IO uint32_t DAC_SYNC_CTRL; + __IO uint32_t PDMA_REQUEST; + uint32_t RESERVED0[10]; + __O uint32_t PC0_LO; + __O uint32_t PC0_HI; + __IO uint32_t PC0_CTRL; + __IO uint32_t PC0_DLY; + __IO uint32_t ADC0_CONV_CTRL; + __IO uint32_t ADC0_STC; + __IO uint32_t ADC0_TVC; + __IO uint32_t ADC0_MISC_CTRL; + __IO uint32_t DAC0_CTRL; + __IO uint32_t DAC0_BYTE0; + __IO uint32_t DAC0_BYTE1; + __IO uint32_t DAC0_BYTE2; + __IO uint32_t LC0; + __O uint32_t LC0_JMP_LO; + __O uint32_t LC0_JMP_HI; + __O uint32_t PC0_FLAGS; + __O uint32_t PC1_LO; + __O uint32_t PC1_HI; + __IO uint32_t PC1_CTRL; + __IO uint32_t PC1_DLY; + __IO uint32_t ADC1_CONV_CTRL; + __IO uint32_t ADC1_STC; + __IO uint32_t ADC1_TVC; + __IO uint32_t ADC1_MISC_CTRL; + __IO uint32_t DAC1_CTRL; + __IO uint32_t DAC1_BYTE0; + __IO uint32_t DAC1_BYTE1; + __IO uint32_t DAC1_BYTE2; + __IO uint32_t LC1; + __O uint32_t LC1_JMP_LO; + __O uint32_t LC1_JMP_HI; + __O uint32_t PC1_FLAGS; + __O uint32_t PC2_LO; + __O uint32_t PC2_HI; + __IO uint32_t PC2_CTRL; + __IO uint32_t PC2_DLY; + __IO uint32_t ADC2_CONV_CTRL; + __IO uint32_t ADC2_STC; + __IO uint32_t ADC2_TVC; + __IO uint32_t ADC2_MISC_CTRL; + __IO uint32_t DAC2_CTRL; + __IO uint32_t DAC2_BYTE0; + __IO uint32_t DAC2_BYTE1; + __IO uint32_t DAC2_BYTE2; + __IO uint32_t LC2; + __O uint32_t LC2_JMP_LO; + __O uint32_t LC2_JMP_HI; + __O uint32_t PC2_FLAGS; + uint32_t RESERVED1; + uint32_t RESERVED2; + __IO uint32_t SSE_RAM_LO_IDATA; + __IO uint32_t SSE_RAM_HI_IDATA; + uint32_t RESERVED3[61]; + AQ_config_t ACB_DATA[6]; + uint32_t RESERVED4[59]; + __IO uint32_t SSE_PC0; + __IO uint32_t SSE_PC1; + __IO uint32_t SSE_PC2; + uint32_t RESERVED5[57]; + __IO uint32_t SSE_DAC0_BYTES01; + __IO uint32_t SSE_DAC1_BYTES01; + __IO uint32_t SSE_DAC2_BYTES01; + uint32_t RESERVED6[61]; + __O uint32_t SSE_ADC0_RESULTS; + __O uint32_t SSE_ADC1_RESULTS; + __O uint32_t SSE_ADC2_RESULTS; + uint32_t RESERVED7[61]; + __O uint32_t SSE_PDMA_DATAIN; + uint32_t RESERVED8[63]; + __IO uint32_t SSE_RAM_DATA[512]; + __I uint32_t ADC0_STATUS; + __I uint32_t ADC1_STATUS; + __I uint32_t ADC2_STATUS; + __I uint32_t COMPARATOR_STATUS; + uint32_t RESERVED9[124]; + __IO uint32_t SSE_IRQ_EN; + __I uint32_t SSE_IRQ; + __O uint32_t SSE_IRQ_CLR; + __IO uint32_t COMP_IRQ_EN; + __I uint32_t COMP_IRQ; + __O uint32_t COMP_IRQ_CLR; + __IO uint32_t PPE_FIFO_IRQ_EN; + __I uint32_t PPE_FIFO_IRQ; + __O uint32_t PPE_FIFO_IRQ_CLR; + __IO uint32_t PPE_FLAGS0_IRQ_EN; + __I uint32_t PPE_FLAGS0_IRQ; + __O uint32_t PPE_FLAGS0_IRQ_CLR; + __IO uint32_t PPE_FLAGS1_IRQ_EN; + __I uint32_t PPE_FLAGS1_IRQ; + __O uint32_t PPE_FLAGS1_IRQ_CLR; + __IO uint32_t PPE_FLAGS2_IRQ_EN; + __I uint32_t PPE_FLAGS2_IRQ; + __O uint32_t PPE_FLAGS2_IRQ_CLR; + __IO uint32_t PPE_FLAGS3_IRQ_EN; + __I uint32_t PPE_FLAGS3_IRQ; + __O uint32_t PPE_FLAGS3_IRQ_CLR; + __IO uint32_t PPE_SFFLAGS_IRQ_EN; + __I uint32_t PPE_SFFLAGS_IRQ; + __O uint32_t PPE_SFFLAGS_IRQ_CLR; + __IO uint32_t FPGA_FLAGS_SEL; + uint32_t RESERVED10[39]; + __IO uint32_t PPE_PDMA_CTRL; + __I uint32_t PDMA_STATUS; + __IO uint32_t PPE_PDMA_DATAOUT; + uint32_t RESERVED11[61]; + __I uint32_t PPE_NOP; + __IO uint32_t PPE_CTRL; + __IO uint32_t PPE_PC_ETC; + __IO uint32_t PPE_SF; + __IO uint32_t PPE_SCRATCH; + uint32_t RESERVED12; + __IO uint32_t ALU_CTRL; + __I uint32_t ALU_STATUS; + __IO uint32_t ALU_A; + uint32_t RESERVED50; + __IO uint32_t ALU_B; + uint32_t RESERVED53; + __IO uint32_t ALU_C; + uint32_t RESERVED51; + __IO uint32_t ALU_D; + uint32_t RESERVED52; + __IO uint32_t ALU_E; + uint32_t RESERVED54; + __IO uint32_t PPE_FPTR; + uint32_t RESERVED55; + __IO uint32_t PPE_FLAGS0; + __IO uint32_t PPE_FLAGS1; + __IO uint32_t PPE_FLAGS2; + __IO uint32_t PPE_FLAGS3; + __IO uint32_t PPE_SFFLAGS; + uint32_t RESERVED13[11]; + __IO uint32_t ADC0_FIFO_CTRL; + __I uint32_t ADC0_FIFO_STATUS; + __IO uint32_t ADC0_FIFO_DATA; + __IO uint32_t ADC1_FIFO_CTRL; + __I uint32_t ADC1_FIFO_STATUS; + __IO uint32_t ADC1_FIFO_DATA; + __IO uint32_t ADC2_FIFO_CTRL; + __I uint32_t ADC2_FIFO_STATUS; + __IO uint32_t ADC2_FIFO_DATA; + uint32_t RESERVED14[19]; + __I uint32_t ADC0_FIFO_DATA_PEEK; + __I uint32_t ADC0_FIFO_DATA0; + __I uint32_t ADC0_FIFO_DATA1; + __I uint32_t ADC0_FIFO_DATA2; + __I uint32_t ADC0_FIFO_DATA3; + __I uint32_t ADC1_FIFO_DATA_PEEK; + __I uint32_t ADC1_FIFO_DATA0; + __I uint32_t ADC1_FIFO_DATA1; + __I uint32_t ADC1_FIFO_DATA2; + __I uint32_t ADC1_FIFO_DATA3; + __I uint32_t ADC2_FIFO_DATA_PEEK; + __I uint32_t ADC2_FIFO_DATA0; + __I uint32_t ADC2_FIFO_DATA1; + __I uint32_t ADC2_FIFO_DATA2; + __I uint32_t ADC2_FIFO_DATA3; + uint32_t RESERVED15[177]; + __IO uint32_t PPE_RAM_DATA[512]; +} ACE_TypeDef; + +/*----------------------------------------------------------------------------*/ +/*------------------------ In Application Programming ------------------------*/ +/*----------------------------------------------------------------------------*/ +typedef struct +{ + __IO uint32_t IAP_IR; + __IO uint32_t IAP_DR2; + __IO uint32_t IAP_DR3; + __IO uint32_t IAP_DR5; + __IO uint32_t IAP_DR26; + __IO uint32_t IAP_DR32; + __IO uint32_t IAP_DR; + __IO uint32_t IAP_DR_LENGTH; + __IO uint32_t IAP_TAP_NEW_STATE; + __IO uint32_t IAP_TAP_CONTROL; + __I uint32_t IAP_STATUS; +} IAP_TypeDef; + +/*----------------------------------------------------------------------------*/ +/*---------------------- eNVM Special Function Registers ---------------------*/ +/*----------------------------------------------------------------------------*/ +typedef struct +{ + __IO uint32_t STATUS; + __IO uint32_t CONTROL; + __IO uint32_t ENABLE; + uint32_t RESERVED0; + __IO uint32_t CONFIG_0; + __IO uint32_t CONFIG_1; + __IO uint32_t PAGE_STATUS_0; + __IO uint32_t PAGE_STATUS_1; + __IO uint32_t SEGMENT; + __IO uint32_t ENVM_SELECT; +} NVM_TypeDef; + +/*----------------------------------------------------------------------------*/ +/*---------------------- eNVM Special Function Registers ---------------------*/ +/*----------------------------------------------------------------------------*/ +typedef struct +{ + __IO uint32_t MSSIRQ_EN0; + __IO uint32_t MSSIRQ_EN1; + __IO uint32_t MSSIRQ_EN2; + __IO uint32_t MSSIRQ_EN3; + __IO uint32_t MSSIRQ_EN4; + __IO uint32_t MSSIRQ_EN5; + __IO uint32_t MSSIRQ_EN6; + __IO uint32_t MSSIRQ_EN7; + __I uint32_t MSSIRQ_SRC0; + __I uint32_t MSSIRQ_SRC1; + __I uint32_t MSSIRQ_SRC2; + __I uint32_t MSSIRQ_SRC3; + __I uint32_t MSSIRQ_SRC4; + __I uint32_t MSSIRQ_SRC5; + __I uint32_t MSSIRQ_SRC6; + __I uint32_t MSSIRQ_SRC7; + __IO uint32_t FIIC_MR; +} MSS_IRQ_CTRL_TypeDef; + +/*----------------------------------------------------------------------------*/ +/*------------------------------ System Registers ----------------------------*/ +/*----------------------------------------------------------------------------*/ +typedef struct +{ + __IO uint32_t ESRAM_CR; + __IO uint32_t ENVM_CR; + __IO uint32_t ENVM_REMAP_SYS_CR; + __IO uint32_t ENVM_REMAP_FAB_CR; + __IO uint32_t FAB_PROT_SIZE_CR; + __IO uint32_t FAB_PROT_BASE_CR; + __IO uint32_t AHB_MATRIX_CR; + __IO uint32_t MSS_SR; + __IO uint32_t CLR_MSS_SR; + __IO uint32_t EFROM_CR; + __IO uint32_t IAP_CR; + __IO uint32_t SOFT_IRQ_CR; + __IO uint32_t SOFT_RST_CR; + __IO uint32_t DEVICE_SR; + __IO uint32_t SYSTICK_CR; + __IO uint32_t EMC_MUX_CR; + __IO uint32_t EMC_CS_0_CR; + __IO uint32_t EMC_CS_1_CR; + __IO uint32_t MSS_CLK_CR; + __IO uint32_t MSS_CCC_DIV_CR; + __IO uint32_t MSS_CCC_MUX_CR; + __IO uint32_t MSS_CCC_PLL_CR; + __IO uint32_t MSS_CCC_DLY_CR; + __IO uint32_t MSS_CCC_SR; + __IO uint32_t MSS_RCOSC_CR; + __IO uint32_t VRPSM_CR; + __IO uint32_t RESERVED; + __IO uint32_t FAB_IF_CR; + __IO uint32_t FAB_APB_HIWORD_DR; + __IO uint32_t LOOPBACK_CR; + __IO uint32_t MSS_IO_BANK_CR; + __IO uint32_t GPIN_SOURCE_CR; + __IO uint32_t TEST_SR; + __IO uint32_t RED_REP_ADDR0; + __I uint32_t RED_REP_LOW_LOCS0; + __I uint32_t RED_REP_HIGH_LOCS0; + __IO uint32_t RED_REP_ADDR1; + __I uint32_t RED_REP_LOW_LOCS1; + __I uint32_t RED_REP_HIGH_LOCS1; + __IO uint32_t FABRIC_CR; + uint32_t RESERVED1[24]; + __IO uint32_t IOMUX_CR[83]; +} SYSREG_TypeDef; + +#define SYSREG_ENVM_SOFTRESET_MASK (uint32_t)0x00000001 +#define SYSREG_ESRAM0_SOFTRESET_MASK (uint32_t)0x00000002 +#define SYSREG_ESRAM1_SOFTRESET_MASK (uint32_t)0x00000004 +#define SYSREG_EMC_SOFTRESET_MASK (uint32_t)0x00000008 +#define SYSREG_MAC_SOFTRESET_MASK (uint32_t)0x00000010 +#define SYSREG_PDMA_SOFTRESET_MASK (uint32_t)0x00000020 +#define SYSREG_TIMER_SOFTRESET_MASK (uint32_t)0x00000040 +#define SYSREG_UART0_SOFTRESET_MASK (uint32_t)0x00000080 +#define SYSREG_UART1_SOFTRESET_MASK (uint32_t)0x00000100 +#define SYSREG_SPI0_SOFTRESET_MASK (uint32_t)0x00000200 +#define SYSREG_SPI1_SOFTRESET_MASK (uint32_t)0x00000400 +#define SYSREG_I2C0_SOFTRESET_MASK (uint32_t)0x00000800 +#define SYSREG_I2C1_SOFTRESET_MASK (uint32_t)0x00001000 +#define SYSREG_ACE_SOFTRESET_MASK (uint32_t)0x00002000 +#define SYSREG_GPIO_SOFTRESET_MASK (uint32_t)0x00004000 +#define SYSREG_IAP_SOFTRESET_MASK (uint32_t)0x00008000 +#define SYSREG_EXT_SOFTRESET_MASK (uint32_t)0x00010000 +#define SYSREG_FPGA_SOFTRESET_MASK (uint32_t)0x00020000 +#define SYSREG_F2M_RESET_ENABLE_MASK (uint32_t)0x00040000 +#define SYSREG_PADRESET_ENABLE_MASK (uint32_t)0x00080000 + +/******************************************************************************/ +/* Peripheral memory map */ +/******************************************************************************/ +#define UART0_BASE 0x40000000U +#define SPI0_BASE 0x40001000U +#define I2C0_BASE 0x40002000U +#define MAC_BASE 0x40003000U +#define PDMA_BASE 0x40004000U +#define TIMER_BASE 0x40005000U +#define WATCHDOG_BASE 0x40006000U +#define H2F_IRQ_CTRL_BASE 0x40007000U +#define UART1_BASE 0x40010000U +#define SPI1_BASE 0x40011000U +#define I2C1_BASE 0x40012000U +#define GPIO_BASE 0x40013000U +#define RTC_BASE 0x40014100U +#define FROM_BASE 0x40015000U +#define IAP_BASE 0x40016000U +#define ACE_BASE 0x40020000U +#define FPGA_FABRIC_RAM_BASE 0x40040000U +#define FPGA_FABRIC_BASE 0x40050000U +#define ENVM_BASE 0x60000000U +#define ENVM_REGS_BASE 0x60100000U +#define SYSREG_BASE 0xE0042000U + +/******************************************************************************/ +/* bitband address calcualtion macro */ +/******************************************************************************/ +#define BITBAND_ADDRESS(X) ((X & 0xF0000000U) + 0x02000000U + ((X & 0xFFFFFU) << 5)) + +/******************************************************************************/ +/* Peripheral declaration */ +/******************************************************************************/ +#define UART0 ((UART_TypeDef *) UART0_BASE) +#define UART0_BITBAND ((UART_BitBand_TypeDef *) BITBAND_ADDRESS(UART0_BASE)) +#define SPI0 ((SPI_TypeDef *) SPI0_BASE) +#define SPI0_BITBAND ((SPI_BitBand_TypeDef *) BITBAND_ADDRESS(SPI0_BASE)) +#define I2C0 ((I2C_TypeDef *) I2C0_BASE) +#define I2C0_BITBAND ((I2C_BitBand_TypeDef *) BITBAND_ADDRESS(I2C0_BASE)) +#define MAC ((MAC_TypeDef *) MAC_BASE) +#define PDMA ((PDMA_TypeDef *) PDMA_BASE) +#define TIMER ((TIMER_TypeDef *) TIMER_BASE) +#define TIMER_BITBAND ((TIMER_BitBand_TypeDef *) BITBAND_ADDRESS(TIMER_BASE)) +#define WATCHDOG ((WATCHDOG_TypeDef *) WATCHDOG_BASE) +#define MSS_IRQ_CTRL ((MSS_IRQ_CTRL_TypeDef *) H2F_IRQ_CTRL_BASE) +#define UART1 ((UART_TypeDef *) UART1_BASE) +#define UART1_BITBAND ((UART_BitBand_TypeDef *) BITBAND_ADDRESS(UART1_BASE)) +#define SPI1 ((SPI_TypeDef *) SPI1_BASE) +#define SPI1_BITBAND ((SPI_BitBand_TypeDef *) BITBAND_ADDRESS(SPI1_BASE)) +#define I2C1 ((I2C_TypeDef *) I2C1_BASE) +#define I2C1_BITBAND ((I2C_BitBand_TypeDef *) BITBAND_ADDRESS(I2C1_BASE)) +#define GPIO ((GPIO_TypeDef *) GPIO_BASE) +#define GPIO_BITBAND ((GPIO_BitBand_TypeDef *) BITBAND_ADDRESS(GPIO_BASE)) +#define RTC ((RTC_TypeDef *) RTC_BASE) +#define FROM ((void *) FROM_BASE) +#define IAP ((IAP_TypeDef *) IAP_BASE) +#define ACE ((ACE_TypeDef *) ACE_BASE) +#define FPGA_FABRIC_RAM ((void *) FPGA_FABRIC_RAM_BASE) +#define FPGA_FABRIC ((void *) FPGA_FABRIC_BASE) +#define ENVM ((void *) ENVM_BASE) +#define ENVM_REGS ((NVM_TypeDef *) ENVM_REGS_BASE) +#define SYSREG ((SYSREG_TypeDef *) SYSREG_BASE) + +#ifdef __cplusplus +} +#endif + +#endif /* __A2FXXXM3_H__ */ + diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/core_cm3.c b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/core_cm3.c new file mode 100644 index 000000000..56fddc52b --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/core_cm3.c @@ -0,0 +1,784 @@ +/**************************************************************************//** + * @file core_cm3.c + * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Source File + * @version V1.30 + * @date 30. October 2009 + * + * @note + * Copyright (C) 2009 ARM Limited. All rights reserved. + * + * @par + * ARM Limited (ARM) is supplying this software for use with Cortex-M + * processor based microcontrollers. This file can be freely distributed + * within development tools that are supporting such ARM based processors. + * + * @par + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + * + ******************************************************************************/ + +#include + +/* define compiler specific symbols */ +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */ + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + +#endif + + +/* ################### Compiler specific Intrinsics ########################### */ + +#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ +/* ARM armcc specific functions */ + +/** + * @brief Return the Process Stack Pointer + * + * @return ProcessStackPointer + * + * Return the actual process stack pointer + */ +__ASM uint32_t __get_PSP(void) +{ + mrs r0, psp + bx lr +} + +/** + * @brief Set the Process Stack Pointer + * + * @param topOfProcStack Process Stack Pointer + * + * Assign the value ProcessStackPointer to the MSP + * (process stack pointer) Cortex processor register + */ +__ASM void __set_PSP(uint32_t topOfProcStack) +{ + msr psp, r0 + bx lr +} + +/** + * @brief Return the Main Stack Pointer + * + * @return Main Stack Pointer + * + * Return the current value of the MSP (main stack pointer) + * Cortex processor register + */ +__ASM uint32_t __get_MSP(void) +{ + mrs r0, msp + bx lr +} + +/** + * @brief Set the Main Stack Pointer + * + * @param topOfMainStack Main Stack Pointer + * + * Assign the value mainStackPointer to the MSP + * (main stack pointer) Cortex processor register + */ +__ASM void __set_MSP(uint32_t mainStackPointer) +{ + msr msp, r0 + bx lr +} + +/** + * @brief Reverse byte order in unsigned short value + * + * @param value value to reverse + * @return reversed value + * + * Reverse byte order in unsigned short value + */ +__ASM uint32_t __REV16(uint16_t value) +{ + rev16 r0, r0 + bx lr +} + +/** + * @brief Reverse byte order in signed short value with sign extension to integer + * + * @param value value to reverse + * @return reversed value + * + * Reverse byte order in signed short value with sign extension to integer + */ +__ASM int32_t __REVSH(int16_t value) +{ + revsh r0, r0 + bx lr +} + + +#if (__ARMCC_VERSION < 400000) + +/** + * @brief Remove the exclusive lock created by ldrex + * + * Removes the exclusive lock which is created by ldrex. + */ +__ASM void __CLREX(void) +{ + clrex +} + +/** + * @brief Return the Base Priority value + * + * @return BasePriority + * + * Return the content of the base priority register + */ +__ASM uint32_t __get_BASEPRI(void) +{ + mrs r0, basepri + bx lr +} + +/** + * @brief Set the Base Priority value + * + * @param basePri BasePriority + * + * Set the base priority register + */ +__ASM void __set_BASEPRI(uint32_t basePri) +{ + msr basepri, r0 + bx lr +} + +/** + * @brief Return the Priority Mask value + * + * @return PriMask + * + * Return state of the priority mask bit from the priority mask register + */ +__ASM uint32_t __get_PRIMASK(void) +{ + mrs r0, primask + bx lr +} + +/** + * @brief Set the Priority Mask value + * + * @param priMask PriMask + * + * Set the priority mask bit in the priority mask register + */ +__ASM void __set_PRIMASK(uint32_t priMask) +{ + msr primask, r0 + bx lr +} + +/** + * @brief Return the Fault Mask value + * + * @return FaultMask + * + * Return the content of the fault mask register + */ +__ASM uint32_t __get_FAULTMASK(void) +{ + mrs r0, faultmask + bx lr +} + +/** + * @brief Set the Fault Mask value + * + * @param faultMask faultMask value + * + * Set the fault mask register + */ +__ASM void __set_FAULTMASK(uint32_t faultMask) +{ + msr faultmask, r0 + bx lr +} + +/** + * @brief Return the Control Register value + * + * @return Control value + * + * Return the content of the control register + */ +__ASM uint32_t __get_CONTROL(void) +{ + mrs r0, control + bx lr +} + +/** + * @brief Set the Control Register value + * + * @param control Control value + * + * Set the control register + */ +__ASM void __set_CONTROL(uint32_t control) +{ + msr control, r0 + bx lr +} + +#endif /* __ARMCC_VERSION */ + + + +#elif (defined (__ICCARM__)) /*------------------ ICC Compiler -------------------*/ +/* IAR iccarm specific functions */ +#pragma diag_suppress=Pe940 + +/** + * @brief Return the Process Stack Pointer + * + * @return ProcessStackPointer + * + * Return the actual process stack pointer + */ +uint32_t __get_PSP(void) +{ + __ASM("mrs r0, psp"); + __ASM("bx lr"); +} + +/** + * @brief Set the Process Stack Pointer + * + * @param topOfProcStack Process Stack Pointer + * + * Assign the value ProcessStackPointer to the MSP + * (process stack pointer) Cortex processor register + */ +void __set_PSP(uint32_t topOfProcStack) +{ + __ASM("msr psp, r0"); + __ASM("bx lr"); +} + +/** + * @brief Return the Main Stack Pointer + * + * @return Main Stack Pointer + * + * Return the current value of the MSP (main stack pointer) + * Cortex processor register + */ +uint32_t __get_MSP(void) +{ + __ASM("mrs r0, msp"); + __ASM("bx lr"); +} + +/** + * @brief Set the Main Stack Pointer + * + * @param topOfMainStack Main Stack Pointer + * + * Assign the value mainStackPointer to the MSP + * (main stack pointer) Cortex processor register + */ +void __set_MSP(uint32_t topOfMainStack) +{ + __ASM("msr msp, r0"); + __ASM("bx lr"); +} + +/** + * @brief Reverse byte order in unsigned short value + * + * @param value value to reverse + * @return reversed value + * + * Reverse byte order in unsigned short value + */ +uint32_t __REV16(uint16_t value) +{ + __ASM("rev16 r0, r0"); + __ASM("bx lr"); +} + +/** + * @brief Reverse bit order of value + * + * @param value value to reverse + * @return reversed value + * + * Reverse bit order of value + */ +uint32_t __RBIT(uint32_t value) +{ + __ASM("rbit r0, r0"); + __ASM("bx lr"); +} + +/** + * @brief LDR Exclusive (8 bit) + * + * @param *addr address pointer + * @return value of (*address) + * + * Exclusive LDR command for 8 bit values) + */ +uint8_t __LDREXB(uint8_t *addr) +{ + __ASM("ldrexb r0, [r0]"); + __ASM("bx lr"); +} + +/** + * @brief LDR Exclusive (16 bit) + * + * @param *addr address pointer + * @return value of (*address) + * + * Exclusive LDR command for 16 bit values + */ +uint16_t __LDREXH(uint16_t *addr) +{ + __ASM("ldrexh r0, [r0]"); + __ASM("bx lr"); +} + +/** + * @brief LDR Exclusive (32 bit) + * + * @param *addr address pointer + * @return value of (*address) + * + * Exclusive LDR command for 32 bit values + */ +uint32_t __LDREXW(uint32_t *addr) +{ + __ASM("ldrex r0, [r0]"); + __ASM("bx lr"); +} + +/** + * @brief STR Exclusive (8 bit) + * + * @param value value to store + * @param *addr address pointer + * @return successful / failed + * + * Exclusive STR command for 8 bit values + */ +uint32_t __STREXB(uint8_t value, uint8_t *addr) +{ + __ASM("strexb r0, r0, [r1]"); + __ASM("bx lr"); +} + +/** + * @brief STR Exclusive (16 bit) + * + * @param value value to store + * @param *addr address pointer + * @return successful / failed + * + * Exclusive STR command for 16 bit values + */ +uint32_t __STREXH(uint16_t value, uint16_t *addr) +{ + __ASM("strexh r0, r0, [r1]"); + __ASM("bx lr"); +} + +/** + * @brief STR Exclusive (32 bit) + * + * @param value value to store + * @param *addr address pointer + * @return successful / failed + * + * Exclusive STR command for 32 bit values + */ +uint32_t __STREXW(uint32_t value, uint32_t *addr) +{ + __ASM("strex r0, r0, [r1]"); + __ASM("bx lr"); +} + +#pragma diag_default=Pe940 + + +#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/ +/* GNU gcc specific functions */ + +/** + * @brief Return the Process Stack Pointer + * + * @return ProcessStackPointer + * + * Return the actual process stack pointer + */ +uint32_t __get_PSP(void) __attribute__( ( naked ) ); +uint32_t __get_PSP(void) +{ + uint32_t result=0; + + __ASM volatile ("MRS %0, psp\n\t" + "MOV r0, %0 \n\t" + "BX lr \n\t" : "=r" (result) ); + return(result); +} + +/** + * @brief Set the Process Stack Pointer + * + * @param topOfProcStack Process Stack Pointer + * + * Assign the value ProcessStackPointer to the MSP + * (process stack pointer) Cortex processor register + */ +void __set_PSP(uint32_t topOfProcStack) __attribute__( ( naked ) ); +void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0\n\t" + "BX lr \n\t" : : "r" (topOfProcStack) ); +} + +/** + * @brief Return the Main Stack Pointer + * + * @return Main Stack Pointer + * + * Return the current value of the MSP (main stack pointer) + * Cortex processor register + */ +uint32_t __get_MSP(void) __attribute__( ( naked ) ); +uint32_t __get_MSP(void) +{ + uint32_t result=0; + + __ASM volatile ("MRS %0, msp\n\t" + "MOV r0, %0 \n\t" + "BX lr \n\t" : "=r" (result) ); + return(result); +} + +/** + * @brief Set the Main Stack Pointer + * + * @param topOfMainStack Main Stack Pointer + * + * Assign the value mainStackPointer to the MSP + * (main stack pointer) Cortex processor register + */ +void __set_MSP(uint32_t topOfMainStack) __attribute__( ( naked ) ); +void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0\n\t" + "BX lr \n\t" : : "r" (topOfMainStack) ); +} + +/** + * @brief Return the Base Priority value + * + * @return BasePriority + * + * Return the content of the base priority register + */ +uint32_t __get_BASEPRI(void) +{ + uint32_t result=0; + + __ASM volatile ("MRS %0, basepri_max" : "=r" (result) ); + return(result); +} + +/** + * @brief Set the Base Priority value + * + * @param basePri BasePriority + * + * Set the base priority register + */ +void __set_BASEPRI(uint32_t value) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (value) ); +} + +/** + * @brief Return the Priority Mask value + * + * @return PriMask + * + * Return state of the priority mask bit from the priority mask register + */ +uint32_t __get_PRIMASK(void) +{ + uint32_t result=0; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + +/** + * @brief Set the Priority Mask value + * + * @param priMask PriMask + * + * Set the priority mask bit in the priority mask register + */ +void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) ); +} + +/** + * @brief Return the Fault Mask value + * + * @return FaultMask + * + * Return the content of the fault mask register + */ +uint32_t __get_FAULTMASK(void) +{ + uint32_t result=0; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + +/** + * @brief Set the Fault Mask value + * + * @param faultMask faultMask value + * + * Set the fault mask register + */ +void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) ); +} + +/** + * @brief Return the Control Register value +* +* @return Control value + * + * Return the content of the control register + */ +uint32_t __get_CONTROL(void) +{ + uint32_t result=0; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + +/** + * @brief Set the Control Register value + * + * @param control Control value + * + * Set the control register + */ +void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) ); +} + + +/** + * @brief Reverse byte order in integer value + * + * @param value value to reverse + * @return reversed value + * + * Reverse byte order in integer value + */ +uint32_t __REV(uint32_t value) +{ + uint32_t result=0; + + __ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + +/** + * @brief Reverse byte order in unsigned short value + * + * @param value value to reverse + * @return reversed value + * + * Reverse byte order in unsigned short value + */ +uint32_t __REV16(uint16_t value) +{ + uint32_t result=0; + + __ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + +/** + * @brief Reverse byte order in signed short value with sign extension to integer + * + * @param value value to reverse + * @return reversed value + * + * Reverse byte order in signed short value with sign extension to integer + */ +int32_t __REVSH(int16_t value) +{ + uint32_t result=0; + + __ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + +/** + * @brief Reverse bit order of value + * + * @param value value to reverse + * @return reversed value + * + * Reverse bit order of value + */ +uint32_t __RBIT(uint32_t value) +{ + uint32_t result=0; + + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + +/** + * @brief LDR Exclusive (8 bit) + * + * @param *addr address pointer + * @return value of (*address) + * + * Exclusive LDR command for 8 bit value + */ +uint8_t __LDREXB(uint8_t *addr) +{ + uint8_t result=0; + + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) ); + return(result); +} + +/** + * @brief LDR Exclusive (16 bit) + * + * @param *addr address pointer + * @return value of (*address) + * + * Exclusive LDR command for 16 bit values + */ +uint16_t __LDREXH(uint16_t *addr) +{ + uint16_t result=0; + + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) ); + return(result); +} + +/** + * @brief LDR Exclusive (32 bit) + * + * @param *addr address pointer + * @return value of (*address) + * + * Exclusive LDR command for 32 bit values + */ +uint32_t __LDREXW(uint32_t *addr) +{ + uint32_t result=0; + + __ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) ); + return(result); +} + +/** + * @brief STR Exclusive (8 bit) + * + * @param value value to store + * @param *addr address pointer + * @return successful / failed + * + * Exclusive STR command for 8 bit values + */ +uint32_t __STREXB(uint8_t value, uint8_t *addr) +{ + uint32_t result=0; + + __ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); + return(result); +} + +/** + * @brief STR Exclusive (16 bit) + * + * @param value value to store + * @param *addr address pointer + * @return successful / failed + * + * Exclusive STR command for 16 bit values + */ +uint32_t __STREXH(uint16_t value, uint16_t *addr) +{ + uint32_t result=0; + + __ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); + return(result); +} + +/** + * @brief STR Exclusive (32 bit) + * + * @param value value to store + * @param *addr address pointer + * @return successful / failed + * + * Exclusive STR command for 32 bit values + */ +uint32_t __STREXW(uint32_t value, uint32_t *addr) +{ + uint32_t result=0; + + __ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); + return(result); +} + + +#elif (defined (__TASKING__)) /*------------------ TASKING Compiler ---------------------*/ +/* TASKING carm specific functions */ + +/* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all instrinsics, + * Including the CMSIS ones. + */ + +#endif diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/core_cm3.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/core_cm3.h new file mode 100644 index 000000000..e0565d7d4 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/core_cm3.h @@ -0,0 +1,1818 @@ +/**************************************************************************//** + * @file core_cm3.h + * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File + * @version V1.30 + * @date 30. October 2009 + * + * @note + * Copyright (C) 2009 ARM Limited. All rights reserved. + * + * @par + * ARM Limited (ARM) is supplying this software for use with Cortex-M + * processor based microcontrollers. This file can be freely distributed + * within development tools that are supporting such ARM based processors. + * + * @par + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + * + ******************************************************************************/ + +#ifndef __CM3_CORE_H__ +#define __CM3_CORE_H__ + +/** @addtogroup CMSIS_CM3_core_LintCinfiguration CMSIS CM3 Core Lint Configuration + * + * List of Lint messages which will be suppressed and not shown: + * - Error 10: \n + * register uint32_t __regBasePri __asm("basepri"); \n + * Error 10: Expecting ';' + * . + * - Error 530: \n + * return(__regBasePri); \n + * Warning 530: Symbol '__regBasePri' (line 264) not initialized + * . + * - Error 550: \n + * __regBasePri = (basePri & 0x1ff); \n + * Warning 550: Symbol '__regBasePri' (line 271) not accessed + * . + * - Error 754: \n + * uint32_t RESERVED0[24]; \n + * Info 754: local structure member '' (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_IAR_and_Keil/MicroSemi_Code/CMSIS/mss_assert.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/mss_assert.h new file mode 100644 index 000000000..4725d2132 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/mss_assert.h @@ -0,0 +1,48 @@ +/******************************************************************************* + * (c) Copyright 2009 Actel Corporation. All rights reserved. + * + * Assertion implementation. + * + * This file provides the implementation of the ASSERT macro. This file can be + * modified to cater for project specific requirements regarding the way + * assertions are handled. + * + * SVN $Revision: 1676 $ + * SVN $Date: 2009-12-02 16:47:03 +0000 (Wed, 02 Dec 2009) $ + */ +#ifndef __MSS_ASSERT_H_ +#define __MSS_ASSERT_H_ + +#include + +#if defined ( __GNUC__ ) + +#if defined(NDEBUG) + +#define ASSERT(CHECK) + +#else /* NDEBUG */ +/* + * SoftConsole assertion handling + */ +#define ASSERT(CHECK) \ + do { \ + if (!(CHECK)) \ + { \ + __asm volatile ("BKPT\n\t"); \ + } \ + } while (0); + +#endif /* NDEBUG */ + +#else +/* + * IAR Embedded Workbench or Keil assertion handling. + * Call C library assert function which should result in error message + * displayed in debugger. + */ +#define ASSERT(X) assert(X) + +#endif + +#endif /* __MSS_ASSERT_H_ */ diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/debug-in-actel-smartfusion-envm.ld b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/debug-in-actel-smartfusion-envm.ld new file mode 100644 index 000000000..1d33683f3 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/debug-in-actel-smartfusion-envm.ld @@ -0,0 +1,184 @@ +/******************************************************************************* + * (c) Copyright 2009 Actel Corporation. All rights reserved. + * + * SmartFusion/Cortex-M3 linker script for creating a SoftConsole downloadable + * debug image executing in SmartFusion internal eNVM. + * + * SVN $Revision: 1677 $ + * SVN $Date: 2009-12-02 16:57:29 +0000 (Wed, 02 Dec 2009) $ + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", + "elf32-littlearm") +GROUP(-lc -lgcc -lm) +OUTPUT_ARCH(arm) +ENTRY(Reset_Handler) +SEARCH_DIR(.) +__DYNAMIC = 0; + +/******************************************************************************* + * Start of board customization. + *******************************************************************************/ +MEMORY +{ + /* + * WARNING: The words "SOFTCONSOLE", "FLASH", and "USE", the colon ":", and + * the name of the type of flash memory are all in a specific order. + * Please do not modify that comment line, in order to ensure + * debugging of your application will use the flash memory correctly. + */ + + /* SOFTCONSOLE FLASH USE: actel-smartfusion-envm */ + rom (rx) : ORIGIN = 0x60000000, LENGTH = 256k + + /* SmartFusion internal eNVM mirrored to 0x00000000 */ + romMirror (rx) : ORIGIN = 0x00000000, LENGTH = 256k + + /* SmartFusion internal eSRAM */ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64k +} + +RAM_START_ADDRESS = 0x20000000; /* Must be the same value MEMORY region ram ORIGIN above. */ +RAM_SIZE = 64k; /* Must be the same value MEMORY region ram LENGTH above. */ +MAIN_STACK_SIZE = 8k; /* Cortex main stack size. */ +PROCESS_STACK_SIZE = 4k; /* Cortex process stack size (only available with OS extensions).*/ + +/******************************************************************************* + * End of board customization. + *******************************************************************************/ + +PROVIDE (__main_stack_start = RAM_START_ADDRESS + RAM_SIZE); +PROVIDE (__process_stack_start = __main_stack_start - MAIN_STACK_SIZE); +PROVIDE (_estack = __main_stack_start); +PROVIDE (__mirrored_nvm = 1); /* Indicate to startup code that NVM is mirrored to VMA address and no text copy is required. */ + +SECTIONS +{ + .init : + { + *(.isr_vector) + *sys_boot.o(.text) + . = ALIGN(0x4); + } >romMirror AT>rom + + .text : + { + CREATE_OBJECT_SYMBOLS + __text_load = LOADADDR(.text); + __text_start = .; + + *(.text .text.* .gnu.linkonce.t.*) + *(.plt) + *(.gnu.warning) + *(.glue_7t) *(.glue_7) *(.vfp11_veneer) + + . = ALIGN(0x4); + /* These are for running static constructors and destructors under ELF. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + + *(.rodata .rodata.* .gnu.linkonce.r.*) + + *(.ARM.extab* .gnu.linkonce.armextab.*) + *(.gcc_except_table) + *(.eh_frame_hdr) + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + PROVIDE_HIDDEN (__fini_array_end = .); + } >romMirror AT>rom + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } >ram AT>rom + __exidx_end = .; + _etext = .; + + .data : + { + __data_load = LOADADDR(.data); + _sidata = LOADADDR (.data); + __data_start = .; + _sdata = .; + KEEP(*(.jcr)) + *(.got.plt) *(.got) + *(.shdata) + *(.data .data.* .gnu.linkonce.d.*) + . = ALIGN (4); + _edata = .; + } >ram AT>rom + + .bss : + { + __bss_start__ = . ; + _sbss = .; + *(.shbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + . = ALIGN (8); + __bss_end__ = .; + _end = .; + __end = _end; + _ebss = .; + PROVIDE(end = .); + } >ram AT>rom + + .stab 0 (NOLOAD) : + { + *(.stab) + } + + .stabstr 0 (NOLOAD) : + { + *(.stabstr) + } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } + .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) } + /DISCARD/ : { *(.note.GNU-stack) } +} diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/debug-in-actel-smartfusion-esram.ld b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/debug-in-actel-smartfusion-esram.ld new file mode 100644 index 000000000..85e416044 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/debug-in-actel-smartfusion-esram.ld @@ -0,0 +1,177 @@ +/******************************************************************************* + * (c) Copyright 2009 Actel Corporation. All rights reserved. + * + * SmartFusion/Cortex-M3 linker script for creating a SoftConsole downloadable + * debug image executing in SmartFusion internal eSRAM. + * + * SVN $Revision: 1677 $ + * SVN $Date: 2009-12-02 16:57:29 +0000 (Wed, 02 Dec 2009) $ + */ + + OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", + "elf32-littlearm") +GROUP(-lc -lgcc -lm) +OUTPUT_ARCH(arm) +ENTRY(Reset_Handler) +SEARCH_DIR(.) +__DYNAMIC = 0; + +/******************************************************************************* + * Start of board customization. + *******************************************************************************/ +MEMORY +{ + /* SmartFusion internal eSRAM */ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64k +} + +RAM_START_ADDRESS = 0x20000000; /* Must be the same value MEMORY region ram ORIGIN above. */ +RAM_SIZE = 64k; /* Must be the same value MEMORY region ram LENGTH above. */ +MAIN_STACK_SIZE = 8k; /* Cortex main stack size. */ +PROCESS_STACK_SIZE = 4k; /* Cortex process stack size (only available with OS extensions).*/ + +/******************************************************************************* + * End of board customization. + *******************************************************************************/ + +PROVIDE (__main_stack_start = RAM_START_ADDRESS + RAM_SIZE); +PROVIDE (__process_stack_start = __main_stack_start - MAIN_STACK_SIZE); +PROVIDE (_estack = __main_stack_start); +PROVIDE (__mirrored_nvm = 0); /* Indicate to startup code that NVM is not mirrored to VMA address .text copy is required. */ + +SECTIONS +{ + .text : + { + CREATE_OBJECT_SYMBOLS + __text_load = LOADADDR(.text); + __text_start = .; + *(.isr_vector) + *(.text .text.* .gnu.linkonce.t.*) + *(.plt) + *(.gnu.warning) + *(.glue_7t) *(.glue_7) *(.vfp11_veneer) + + . = ALIGN(0x4); + /* These are for running static constructors and destructors under ELF. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + + *(.rodata .rodata.* .gnu.linkonce.r.*) + + *(.ARM.extab* .gnu.linkonce.armextab.*) + *(.gcc_except_table) + *(.eh_frame_hdr) + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + PROVIDE_HIDDEN (__fini_array_end = .); + } >ram + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } >ram + __exidx_end = .; + _etext = .; + PROVIDE(__text_end = .); + + .data : + { + __data_load = LOADADDR (.data); + _sidata = LOADADDR (.data); + __data_start = .; + _sdata = .; + KEEP(*(.jcr)) + *(.got.plt) *(.got) + *(.shdata) + *(.data .data.* .gnu.linkonce.d.*) + . = ALIGN (4); + _edata = .; + } >ram + + .bss : + { + __bss_start__ = . ; + _sbss = .; + *(.shbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + . = ALIGN (8); + __bss_end__ = .; + _end = .; + __end = _end; + _ebss = .; + PROVIDE(end = .); + } >ram + + /* + * The .stack section is only specified here in order for the linker to generate + * an error if the ram is full. + */ + .stack : + { + . = ALIGN(4); + . += PROCESS_STACK_SIZE; + . = ALIGN(4); + . += MAIN_STACK_SIZE; + . = ALIGN(4); + } >ram + + .stab 0 (NOLOAD) : + { + *(.stab) + } + + .stabstr 0 (NOLOAD) : + { + *(.stabstr) + } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } + .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) } + /DISCARD/ : { *(.note.GNU-stack) *(.isr_vector) } +} diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/debug-in-external-ram.ld b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/debug-in-external-ram.ld new file mode 100644 index 000000000..b2d614d31 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/debug-in-external-ram.ld @@ -0,0 +1,185 @@ +/******************************************************************************* + * (c) Copyright 2009 Actel Corporation. All rights reserved. + * + * SmartFusion/Cortex-M3 linker script for creating a SoftConsole downloadable + * debug image executing in SmartFusion development board external RAM. + * + * SVN $Revision: 2014 $ + * SVN $Date: 2010-01-20 10:37:26 +0000 (Wed, 20 Jan 2010) $ + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", + "elf32-littlearm") +GROUP(-lc -lgcc -lm) +OUTPUT_ARCH(arm) +ENTRY(Reset_Handler) +SEARCH_DIR(.) +__DYNAMIC = 0; + +/******************************************************************************* + * Start of board customization. + *******************************************************************************/ +MEMORY +{ + /* SmartFusion internal eSRAM */ + esram (rwx) : ORIGIN = 0x20000000, LENGTH = 64k + + /* SmartFusion development board external RAM */ + external_ram (rwx) : ORIGIN = 0x70000000, LENGTH = 2M +} + +RAM_START_ADDRESS = 0x70000000; /* Must be the same value MEMORY region ram ORIGIN above. */ +RAM_SIZE = 64k; /* Must be the same value MEMORY region ram LENGTH above. */ +MAIN_STACK_SIZE = 8k; /* Cortex main stack size. */ +PROCESS_STACK_SIZE = 4k; /* Cortex process stack size (only available with OS extensions).*/ + +/******************************************************************************* + * End of board customization. + *******************************************************************************/ + +PROVIDE (__main_stack_start = RAM_START_ADDRESS + RAM_SIZE); +PROVIDE (__process_stack_start = __main_stack_start - MAIN_STACK_SIZE); +PROVIDE (_estack = __main_stack_start); +PROVIDE (__mirrored_nvm = 0); /* Indicate to startup code that NVM is not mirrored to VMA address .text copy is required. */ + +SECTIONS +{ + .init : + { + *(.isr_vector) + . = ALIGN(0x4); + } >esram + + .text : + { + CREATE_OBJECT_SYMBOLS + __text_load = LOADADDR(.text); + __text_start = .; + *(.text .text.* .gnu.linkonce.t.*) + *(.plt) + *(.gnu.warning) + *(.glue_7t) *(.glue_7) *(.vfp11_veneer) + + . = ALIGN(0x4); + /* These are for running static constructors and destructors under ELF. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + + *(.rodata .rodata.* .gnu.linkonce.r.*) + + *(.ARM.extab* .gnu.linkonce.armextab.*) + *(.gcc_except_table) + *(.eh_frame_hdr) + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + PROVIDE_HIDDEN (__fini_array_end = .); + } >external_ram + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } >external_ram + __exidx_end = .; + _etext = .; + PROVIDE(__text_end = .); + + .data : + { + __data_load = LOADADDR (.data); + _sidata = LOADADDR (.data); + __data_start = .; + _sdata = .; + KEEP(*(.jcr)) + *(.got.plt) *(.got) + *(.shdata) + *(.data .data.* .gnu.linkonce.d.*) + . = ALIGN (4); + _edata = .; + } >external_ram + + .bss : + { + __bss_start__ = . ; + _sbss = .; + *(.shbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + . = ALIGN (8); + __bss_end__ = .; + _end = .; + __end = _end; + _ebss = .; + PROVIDE(end = .); + } >external_ram + + /* + * The .stack section is only specified here in order for the linker to generate + * an error if the esram is full. + */ + .stack : + { + . = ALIGN(4); + . += PROCESS_STACK_SIZE; + . = ALIGN(4); + . += MAIN_STACK_SIZE; + . = ALIGN(4); + } >external_ram + + .stab 0 (NOLOAD) : + { + *(.stab) + } + + .stabstr 0 (NOLOAD) : + { + *(.stabstr) + } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } + .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) } + /DISCARD/ : { *(.note.GNU-stack) *(.isr_vector) } +} diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/newlib_stubs.c b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/newlib_stubs.c new file mode 100644 index 000000000..3b42429f1 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/newlib_stubs.c @@ -0,0 +1,247 @@ +/******************************************************************************* + * (c) Copyright 2009 Actel Corporation. All rights reserved. + * + * Stubs for Newlib system calls. + * + * SVN $Revision: 2020 $ + * SVN $Date: 2010-01-20 14:51:50 +0000 (Wed, 20 Jan 2010) $ + */ +#include +#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_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/production-execute-in-place.ld b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/production-execute-in-place.ld new file mode 100644 index 000000000..cfaddb615 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/production-execute-in-place.ld @@ -0,0 +1,172 @@ +/******************************************************************************* + * (c) Copyright 2009 Actel Corporation. All rights reserved. + * + * SmartFusion/Cortex-M3 linker script creating an executable image for use in + * the Libero flow for executing code in place in internal eNVM. + * + * SVN $Revision: 1766 $ + * SVN $Date: 2009-12-11 16:33:35 +0000 (Fri, 11 Dec 2009) $ + */ +OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", + "elf32-littlearm") +GROUP(-lc -lgcc -lm) +OUTPUT_ARCH(arm) +ENTRY(Reset_Handler) +SEARCH_DIR(.) +__DYNAMIC = 0; + +/******************************************************************************* + * Start of board customization. + *******************************************************************************/ +MEMORY +{ + /* SmartFusion internal eNVM */ + rom (rx) : ORIGIN = 0, LENGTH = 256k + + /* SmartFusion internal eSRAM */ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64k +} + +RAM_START_ADDRESS = 0x20000000; /* Must be the same value as MEMORY region ram ORIGIN above. */ +RAM_SIZE = 64k; /* Must be the same value as MEMORY region ram LENGTH above. */ +MAIN_STACK_SIZE = 8k; /* Cortex main stack size. */ +PROCESS_STACK_SIZE = 4k; /* Cortex process stack size (only available with OS extensions).*/ + +/******************************************************************************* + * End of board customization. + *******************************************************************************/ + +PROVIDE (__main_stack_start = RAM_START_ADDRESS + RAM_SIZE); +PROVIDE (__process_stack_start = __main_stack_start - MAIN_STACK_SIZE); +PROVIDE (_estack = __main_stack_start); +PROVIDE (__mirrored_nvm = 0); /* Indicate to startup code that NVM is not mirrored to VMA address .text copy is required. */ + +SECTIONS +{ + .reset : + { + *(.isr_vector) + *sys_boot.o(.text) + . = ALIGN(0x4); + } >rom + + .text : + { + CREATE_OBJECT_SYMBOLS + __text_load = LOADADDR(.text); + __text_start = .; + + *(.text .text.* .gnu.linkonce.t.*) + *(.plt) + *(.gnu.warning) + *(.glue_7t) *(.glue_7) *(.vfp11_veneer) + + . = ALIGN(0x4); + /* These are for running static constructors and destructors under ELF. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + + *(.rodata .rodata.* .gnu.linkonce.r.*) + + *(.ARM.extab* .gnu.linkonce.armextab.*) + *(.gcc_except_table) + *(.eh_frame_hdr) + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + PROVIDE_HIDDEN (__fini_array_end = .); + } >rom + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } >rom + __exidx_end = .; + _etext = .; + + .data : + { + __data_load = LOADADDR(.data); + _sidata = LOADADDR (.data); + __data_start = .; + _sdata = .; + KEEP(*(.jcr)) + *(.got.plt) *(.got) + *(.shdata) + *(.data .data.* .gnu.linkonce.d.*) + . = ALIGN (4); + _edata = .; + } >ram AT>rom + + .bss : + { + __bss_start__ = . ; + _sbss = .; + *(.shbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + . = ALIGN (8); + __bss_end__ = .; + _end = .; + __end = _end; + _ebss = .; + PROVIDE(end = .); + } >ram AT>rom + + .stab 0 (NOLOAD) : + { + *(.stab) + } + + .stabstr 0 (NOLOAD) : + { + *(.stabstr) + } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } + .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) } + /DISCARD/ : { *(.note.GNU-stack) } +} diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/production-relocate-executable.ld b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/production-relocate-executable.ld new file mode 100644 index 000000000..21e613c92 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/production-relocate-executable.ld @@ -0,0 +1,176 @@ +/******************************************************************************* + * (c) Copyright 2009 Actel Corporation. All rights reserved. + * + * SmartFusion/Cortex-M3 linker script creating an executable image for use in + * the Libero flow for relocating executable from internal eNVM to external RAM + * before starting execution. + * + * SVN $Revision: 1766 $ + * SVN $Date: 2009-12-11 16:33:35 +0000 (Fri, 11 Dec 2009) $ + */ +OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", + "elf32-littlearm") +GROUP(-lc -lgcc -lm) +OUTPUT_ARCH(arm) +ENTRY(Reset_Handler) +SEARCH_DIR(.) +__DYNAMIC = 0; + +/******************************************************************************* + * Start of board customization. + *******************************************************************************/ +MEMORY +{ + /* SmartFusion internal eNVM */ + rom (rx) : ORIGIN = 0, LENGTH = 256k + + /* SmartFusion internal eSRAM */ + esram (rwx) : ORIGIN = 0x20000000, LENGTH = 64k + + /* SmartFusion development board external RAM */ + external_ram (rwx) : ORIGIN = 0x70000000, LENGTH = 2M +} + +RAM_START_ADDRESS = 0x20000000; /* Must be the same value as MEMORY region esram ORIGIN above. */ +RAM_SIZE = 64k; /* Must be the same value as MEMORY region esram LENGTH above. */ +MAIN_STACK_SIZE = 8k; /* Cortex main stack size. */ +PROCESS_STACK_SIZE = 4k; /* Cortex process stack size (only available with OS extensions).*/ + +/******************************************************************************* + * End of board customization. + *******************************************************************************/ + +PROVIDE (__main_stack_start = RAM_START_ADDRESS + RAM_SIZE); +PROVIDE (__process_stack_start = __main_stack_start - MAIN_STACK_SIZE); +PROVIDE (_estack = __main_stack_start); +PROVIDE (__mirrored_nvm = 0); /* Indicate to startup code that NVM is not mirrored to VMA address .text copy is required. */ + +SECTIONS +{ + .reset : + { + *(.isr_vector) +/* *sys_boot.o(.text)*/ + . = ALIGN(0x4); + } >rom + + .text : + { + CREATE_OBJECT_SYMBOLS + __text_load = LOADADDR(.text); + __text_start = .; + + *(.text .text.* .gnu.linkonce.t.*) + *(.plt) + *(.gnu.warning) + *(.glue_7t) *(.glue_7) *(.vfp11_veneer) + + . = ALIGN(0x4); + /* These are for running static constructors and destructors under ELF. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + + *(.rodata .rodata.* .gnu.linkonce.r.*) + + *(.ARM.extab* .gnu.linkonce.armextab.*) + *(.gcc_except_table) + *(.eh_frame_hdr) + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + PROVIDE_HIDDEN (__fini_array_end = .); + } >external_ram AT>rom + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } >external_ram AT>rom + __exidx_end = .; + _etext = .; + + .data : + { + __data_load = LOADADDR(.data); + _sidata = LOADADDR (.data); + __data_start = .; + _sdata = .; + KEEP(*(.jcr)) + *(.got.plt) *(.got) + *(.shdata) + *(.data .data.* .gnu.linkonce.d.*) + . = ALIGN (4); + _edata = .; + } >esram AT>rom + + .bss : + { + __bss_start__ = . ; + _sbss = .; + *(.shbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + . = ALIGN (8); + __bss_end__ = .; + _end = .; + __end = _end; + _ebss = .; + PROVIDE(end = .); + } >esram AT>rom + + .stab 0 (NOLOAD) : + { + *(.stab) + } + + .stabstr 0 (NOLOAD) : + { + *(.stabstr) + } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } + .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) } + /DISCARD/ : { *(.note.GNU-stack) } +} diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/startup_a2fxxxm3.s b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/startup_a2fxxxm3.s new file mode 100644 index 000000000..e9e87adca --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/startup_gcc/startup_a2fxxxm3.s @@ -0,0 +1,1504 @@ +/******************************************************************************* + * (c) Copyright 2009 Actel Corporation. All rights reserved. + * + * SmartFusion A2FXXXM3 vector table and startup code. + * + * SVN $Revision: 2068 $ + * SVN $Date: 2010-01-27 17:27:41 +0000 (Wed, 27 Jan 2010) $ + */ + + .syntax unified + .cpu cortex-m3 + .thumb + + +/*============================================================================== + * Vector table + */ + .global g_pfnVectors + .section .isr_vector,"a",%progbits + .type g_pfnVectors, %object + .size g_pfnVectors, .-g_pfnVectors + +g_pfnVectors: + .word _estack + .word Reset_Handler + .word NMI_Handler + .word HardFault_Handler + .word MemManage_Handler + .word BusFault_Handler + .word UsageFault_Handler + .word 0 + .word 0 + .word 0 + .word 0 + .word SVC_Handler + .word DebugMon_Handler + .word 0 + .word PendSV_Handler + .word SysTick_Handler + .word WdogWakeup_IRQHandler + .word BrownOut_1_5V_IRQHandler + .word BrownOut_3_3V_IRQHandler + .word RTC_Match_IRQHandler + .word RTCIF_Pub_IRQHandler + .word EthernetMAC_IRQHandler + .word IAP_IRQHandler + .word ENVM0_IRQHandler + .word ENVM1_IRQHandler + .word DMA_IRQHandler + .word UART0_IRQHandler + .word UART1_IRQHandler + .word SPI0_IRQHandler + .word SPI1_IRQHandler + .word I2C0_IRQHandler + .word I2C0_SMBAlert_IRQHandler + .word I2C0_SMBus_IRQHandler + .word I2C1_IRQHandler + .word I2C1_SMBAlert_IRQHandler + .word I2C1_SMBus_IRQHandler + .word Timer1_IRQHandler + .word Timer2_IRQHandler + .word PLL_Lock_IRQHandler + .word PLL_LockLost_IRQHandler + .word CommError_IRQHandler + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word Fabric_IRQHandler + .word GPIO0_IRQHandler + .word GPIO1_IRQHandler + .word GPIO2_IRQHandler + .word GPIO3_IRQHandler + .word GPIO4_IRQHandler + .word GPIO5_IRQHandler + .word GPIO6_IRQHandler + .word GPIO7_IRQHandler + .word GPIO8_IRQHandler + .word GPIO9_IRQHandler + .word GPIO10_IRQHandler + .word GPIO11_IRQHandler + .word GPIO12_IRQHandler + .word GPIO13_IRQHandler + .word GPIO14_IRQHandler + .word GPIO15_IRQHandler + .word GPIO16_IRQHandler + .word GPIO17_IRQHandler + .word GPIO18_IRQHandler + .word GPIO19_IRQHandler + .word GPIO20_IRQHandler + .word GPIO21_IRQHandler + .word GPIO22_IRQHandler + .word GPIO23_IRQHandler + .word GPIO24_IRQHandler + .word GPIO25_IRQHandler + .word GPIO26_IRQHandler + .word GPIO27_IRQHandler + .word GPIO28_IRQHandler + .word GPIO29_IRQHandler + .word GPIO30_IRQHandler + .word GPIO31_IRQHandler + .word ACE_PC0_Flag0_IRQHandler + .word ACE_PC0_Flag1_IRQHandler + .word ACE_PC0_Flag2_IRQHandler + .word ACE_PC0_Flag3_IRQHandler + .word ACE_PC1_Flag0_IRQHandler + .word ACE_PC1_Flag1_IRQHandler + .word ACE_PC1_Flag2_IRQHandler + .word ACE_PC1_Flag3_IRQHandler + .word ACE_PC2_Flag0_IRQHandler + .word ACE_PC2_Flag1_IRQHandler + .word ACE_PC2_Flag2_IRQHandler + .word ACE_PC2_Flag3_IRQHandler + .word ACE_ADC0_DataValid_IRQHandler + .word ACE_ADC1_DataValid_IRQHandler + .word ACE_ADC2_DataValid_IRQHandler + .word ACE_ADC0_CalDone_IRQHandler + .word ACE_ADC1_CalDone_IRQHandler + .word ACE_ADC2_CalDone_IRQHandler + .word ACE_ADC0_CalStart_IRQHandler + .word ACE_ADC1_CalStart_IRQHandler + .word ACE_ADC2_CalStart_IRQHandler + .word ACE_Comp0_Fall_IRQHandler + .word ACE_Comp1_Fall_IRQHandler + .word ACE_Comp2_Fall_IRQHandler + .word ACE_Comp3_Fall_IRQHandler + .word ACE_Comp4_Fall_IRQHandler + .word ACE_Comp5_Fall_IRQHandler + .word ACE_Comp6_Fall_IRQHandler + .word ACE_Comp7_Fall_IRQHandler + .word ACE_Comp8_Fall_IRQHandler + .word ACE_Comp9_Fall_IRQHandler + .word ACE_Comp10_Fall_IRQHandler + .word ACE_Comp11_Fall_IRQHandler + .word ACE_Comp0_Rise_IRQHandler + .word ACE_Comp1_Rise_IRQHandler + .word ACE_Comp2_Rise_IRQHandler + .word ACE_Comp3_Rise_IRQHandler + .word ACE_Comp4_Rise_IRQHandler + .word ACE_Comp5_Rise_IRQHandler + .word ACE_Comp6_Rise_IRQHandler + .word ACE_Comp7_Rise_IRQHandler + .word ACE_Comp8_Rise_IRQHandler + .word ACE_Comp9_Rise_IRQHandler + .word ACE_Comp10_Rise_IRQHandler + .word ACE_Comp11_Rise_IRQHandler + .word ACE_ADC0_FifoFull_IRQHandler + .word ACE_ADC0_FifoAFull_IRQHandler + .word ACE_ADC0_FifoEmpty_IRQHandler + .word ACE_ADC1_FifoFull_IRQHandler + .word ACE_ADC1_FifoAFull_IRQHandler + .word ACE_ADC1_FifoEmpty_IRQHandler + .word ACE_ADC2_FifoFull_IRQHandler + .word ACE_ADC2_FifoAFull_IRQHandler + .word ACE_ADC2_FifoEmpty_IRQHandler + .word ACE_PPE_Flag0_IRQHandler + .word ACE_PPE_Flag1_IRQHandler + .word ACE_PPE_Flag2_IRQHandler + .word ACE_PPE_Flag3_IRQHandler + .word ACE_PPE_Flag4_IRQHandler + .word ACE_PPE_Flag5_IRQHandler + .word ACE_PPE_Flag6_IRQHandler + .word ACE_PPE_Flag7_IRQHandler + .word ACE_PPE_Flag8_IRQHandler + .word ACE_PPE_Flag9_IRQHandler + .word ACE_PPE_Flag10_IRQHandler + .word ACE_PPE_Flag11_IRQHandler + .word ACE_PPE_Flag12_IRQHandler + .word ACE_PPE_Flag13_IRQHandler + .word ACE_PPE_Flag14_IRQHandler + .word ACE_PPE_Flag15_IRQHandler + .word ACE_PPE_Flag16_IRQHandler + .word ACE_PPE_Flag17_IRQHandler + .word ACE_PPE_Flag18_IRQHandler + .word ACE_PPE_Flag19_IRQHandler + .word ACE_PPE_Flag20_IRQHandler + .word ACE_PPE_Flag21_IRQHandler + .word ACE_PPE_Flag22_IRQHandler + .word ACE_PPE_Flag23_IRQHandler + .word ACE_PPE_Flag24_IRQHandler + .word ACE_PPE_Flag25_IRQHandler + .word ACE_PPE_Flag26_IRQHandler + .word ACE_PPE_Flag27_IRQHandler + .word ACE_PPE_Flag28_IRQHandler + .word ACE_PPE_Flag29_IRQHandler + .word ACE_PPE_Flag30_IRQHandler + .word ACE_PPE_Flag31_IRQHandler + + +/*============================================================================== + * Reset_Handler + */ + .global Reset_Handler + .type Reset_Handler, %function +Reset_Handler: +_start: +/*------------------------------------------------------------------------------ + * Call CMSIS system init function. + * This is not actually required for SmartFusioon as all low initialisations are + * done as part of the system boot. + */ +; ldr r0, =SystemInit +; blx r0 + +/*------------------------------------------------------------------------------ + * Check if the executable is built for NVM LMA mirrored to VMA address. + * This is done for debugging executables running out of eNVM with SoftConsole. + * The .text section should not be copied in this case since both the LMA and + * VMA point at the eNVM despite the LMA and VMa having different values. + */ + ldr r0, =__mirrored_nvm + cmp r0, #0 + bne copy_data + +/*------------------------------------------------------------------------------ + * Copy code section. + */ + ldr r0, =__text_load + ldr r1, =__text_start + ldr r2, =_etext + cmp r0, r1 + beq copy_data +copy_code_loop: + cmp r1, r2 + itt ne + ldrne r3, [r0], #4 + strne r3, [r1], #4 + bne copy_code_loop + +/*------------------------------------------------------------------------------ + * Copy data section. + */ +copy_data: + ldr r0, =__data_load + ldr r1, =__data_start + ldr r2, =_edata + cmp r0, r1 + beq clear_bss +copy_data_loop: + cmp r1, r2 + itt ne + ldrne r3, [r0], #4 + strne r3, [r1], #4 + bne copy_data_loop + +/*------------------------------------------------------------------------------ + * Clear .bss + */ +clear_bss: + ldr r0, =0 + ldr r1, =__bss_start__ + ldr r2, =__bss_end__ +clear_bss_loop: + cmp r1, r2 + it ne + strne r0, [r1], #4 + bne clear_bss_loop + +/*------------------------------------------------------------------------------ + * Call global constructors + */ +call_glob_ctor: + ldr r0, =__libc_init_array + add lr, pc, #3 + bx r0 + +/*------------------------------------------------------------------------------ + * branch to main. + */ +branch_to_main: + mov r0, #0 /* no arguments */ + mov r1, #0 /* no argv either */ + ldr pc, =main + +ExitLoop: + B ExitLoop + +/*============================================================================== + * NMI_Handler + */ + .weak NMI_Handler + .type NMI_Handler, %function +NMI_Handler: + B . + +/*============================================================================== + * HardFault_Handler + */ + .weak HardFault_Handler + .type HardFault_Handler, %function +HardFault_Handler: + B . + +/*============================================================================== + * MemManage_Handler + */ + .weak MemManage_Handler + .type MemManage_Handler, %function +MemManage_Handler: + B . + +/*============================================================================== + * BusFault_Handler + */ + .weak BusFault_Handler + .type BusFault_Handler, %function +BusFault_Handler: + B . + +/*============================================================================== + * UsageFault_Handler + */ + .weak UsageFault_Handler + .type UsageFault_Handler, %function +UsageFault_Handler: + B . + +/*============================================================================== + * SVC_Handler + */ + .weak SVC_Handler + .type SVC_Handler, %function +SVC_Handler: + B . + +/*============================================================================== + * DebugMon_Handler + */ + .weak DebugMon_Handler + .type DebugMon_Handler, %function +DebugMon_Handler: + B . + +/*============================================================================== + * PendSV_Handler + */ + .weak PendSV_Handler + .type PendSV_Handler, %function +PendSV_Handler: + B . + +/*============================================================================== + * SysTick_Handler + */ + .weak SysTick_Handler + .type SysTick_Handler, %function +SysTick_Handler: + B . + +/*============================================================================== + * WdogWakeup_IRQHandler + */ + .weak WdogWakeup_IRQHandler + .type WdogWakeup_IRQHandler, %function +WdogWakeup_IRQHandler: + B . + +/*============================================================================== + * BrownOut_1_5V_IRQHandler + */ + .weak BrownOut_1_5V_IRQHandler + .type BrownOut_1_5V_IRQHandler, %function +BrownOut_1_5V_IRQHandler: + B . + +/*============================================================================== + * BrownOut_3_3V_IRQHandler + */ + .weak BrownOut_3_3V_IRQHandler + .type BrownOut_3_3V_IRQHandler, %function +BrownOut_3_3V_IRQHandler: + B . + +/*============================================================================== + * RTC_Match_IRQHandler + */ + .weak RTC_Match_IRQHandler + .type RTC_Match_IRQHandler, %function +RTC_Match_IRQHandler: + B . + +/*============================================================================== + * RTCIF_Pub_IRQHandler + */ + .weak RTCIF_Pub_IRQHandler + .type RTCIF_Pub_IRQHandler, %function +RTCIF_Pub_IRQHandler: + B . + +/*============================================================================== + * EthernetMAC_IRQHandler + */ + .weak EthernetMAC_IRQHandler + .type EthernetMAC_IRQHandler, %function +EthernetMAC_IRQHandler: + B . + +/*============================================================================== + * IAP_IRQHandler + */ + .weak IAP_IRQHandler + .type IAP_IRQHandler, %function +IAP_IRQHandler: + B . + +/*============================================================================== + * ENVM0_IRQHandler + */ + .weak ENVM0_IRQHandler + .type ENVM0_IRQHandler, %function +ENVM0_IRQHandler: + B . + +/*============================================================================== + * ENVM1_IRQHandler + */ + .weak ENVM1_IRQHandler + .type ENVM1_IRQHandler, %function +ENVM1_IRQHandler: + B . + +/*============================================================================== + * DMA_IRQHandler + */ + .weak DMA_IRQHandler + .type DMA_IRQHandler, %function +DMA_IRQHandler: + B . + +/*============================================================================== + * UART0_IRQHandler + */ + .weak UART0_IRQHandler + .type UART0_IRQHandler, %function +UART0_IRQHandler: + B . + +/*============================================================================== + * UART1_IRQHandler + */ + .weak UART1_IRQHandler + .type UART1_IRQHandler, %function +UART1_IRQHandler: + B . + +/*============================================================================== + * SPI0_IRQHandler + */ + .weak SPI0_IRQHandler + .type SPI0_IRQHandler, %function +SPI0_IRQHandler: + B . + +/*============================================================================== + * SPI1_IRQHandler + */ + .weak SPI1_IRQHandler + .type SPI1_IRQHandler, %function +SPI1_IRQHandler: + B . + +/*============================================================================== + * I2C0_IRQHandler + */ + .weak I2C0_IRQHandler + .type I2C0_IRQHandler, %function +I2C0_IRQHandler: + B . + +/*============================================================================== + * I2C0_SMBAlert_IRQHandler + */ + .weak I2C0_SMBAlert_IRQHandler + .type I2C0_SMBAlert_IRQHandler, %function +I2C0_SMBAlert_IRQHandler: + B . + +/*============================================================================== + * I2C0_SMBus_IRQHandler + */ + .weak I2C0_SMBus_IRQHandler + .type I2C0_SMBus_IRQHandler, %function +I2C0_SMBus_IRQHandler: + B . + +/*============================================================================== + * I2C1_IRQHandler + */ + .weak I2C1_IRQHandler + .type I2C1_IRQHandler, %function +I2C1_IRQHandler: + B . + +/*============================================================================== + * I2C1_SMBAlert_IRQHandler + */ + .weak I2C1_SMBAlert_IRQHandler + .type I2C1_SMBAlert_IRQHandler, %function +I2C1_SMBAlert_IRQHandler: + B . + +/*============================================================================== + * I2C1_SMBus_IRQHandler + */ + .weak I2C1_SMBus_IRQHandler + .type I2C1_SMBus_IRQHandler, %function +I2C1_SMBus_IRQHandler: + B . + +/*============================================================================== + * Timer1_IRQHandler + */ + .weak Timer1_IRQHandler + .type Timer1_IRQHandler, %function +Timer1_IRQHandler: + B . + +/*============================================================================== + * Timer2_IRQHandler + */ + .weak Timer2_IRQHandler + .type Timer2_IRQHandler, %function +Timer2_IRQHandler: + B . + +/*============================================================================== + * PLL_Lock_IRQHandler + */ + .weak PLL_Lock_IRQHandler + .type PLL_Lock_IRQHandler, %function +PLL_Lock_IRQHandler: + B . + +/*============================================================================== + * PLL_LockLost_IRQHandler + */ + .weak PLL_LockLost_IRQHandler + .type PLL_LockLost_IRQHandler, %function +PLL_LockLost_IRQHandler: + B . + +/*============================================================================== + * CommError_IRQHandler + */ + .weak CommError_IRQHandler + .type CommError_IRQHandler, %function +CommError_IRQHandler: + B . + +/*============================================================================== + * Fabric_IRQHandler + */ + .weak Fabric_IRQHandler + .type Fabric_IRQHandler, %function +Fabric_IRQHandler: + B . + +/*============================================================================== + * GPIO0_IRQHandler + */ + .weak GPIO0_IRQHandler + .type GPIO0_IRQHandler, %function +GPIO0_IRQHandler: + B . + +/*============================================================================== + * GPIO1_IRQHandler + */ + .weak GPIO1_IRQHandler + .type GPIO1_IRQHandler, %function +GPIO1_IRQHandler: + B . + +/*============================================================================== + * GPIO2_IRQHandler + */ + .weak GPIO2_IRQHandler + .type GPIO2_IRQHandler, %function +GPIO2_IRQHandler: + B . + +/*============================================================================== + * GPIO3_IRQHandler + */ + .weak GPIO3_IRQHandler + .type GPIO3_IRQHandler, %function +GPIO3_IRQHandler: + B . + +/*============================================================================== + * GPIO4_IRQHandler + */ + .weak GPIO4_IRQHandler + .type GPIO4_IRQHandler, %function +GPIO4_IRQHandler: + B . + +/*============================================================================== + * GPIO5_IRQHandler + */ + .weak GPIO5_IRQHandler + .type GPIO5_IRQHandler, %function +GPIO5_IRQHandler: + B . + +/*============================================================================== + * GPIO6_IRQHandler + */ + .weak GPIO6_IRQHandler + .type GPIO6_IRQHandler, %function +GPIO6_IRQHandler: + B . + +/*============================================================================== + * GPIO7_IRQHandler + */ + .weak GPIO7_IRQHandler + .type GPIO7_IRQHandler, %function +GPIO7_IRQHandler: + B . + +/*============================================================================== + * GPIO8_IRQHandler + */ + .weak GPIO8_IRQHandler + .type GPIO8_IRQHandler, %function +GPIO8_IRQHandler: + B . + +/*============================================================================== + * GPIO9_IRQHandler + */ + .weak GPIO9_IRQHandler + .type GPIO9_IRQHandler, %function +GPIO9_IRQHandler: + B . + +/*============================================================================== + * GPIO10_IRQHandler + */ + .weak GPIO10_IRQHandler + .type GPIO10_IRQHandler, %function +GPIO10_IRQHandler: + B . + +/*============================================================================== + * GPIO11_IRQHandler + */ + .weak GPIO11_IRQHandler + .type GPIO11_IRQHandler, %function +GPIO11_IRQHandler: + B . + +/*============================================================================== + * GPIO12_IRQHandler + */ + .weak GPIO12_IRQHandler + .type GPIO12_IRQHandler, %function +GPIO12_IRQHandler: + B . + +/*============================================================================== + * GPIO13_IRQHandler + */ + .weak GPIO13_IRQHandler + .type GPIO13_IRQHandler, %function +GPIO13_IRQHandler: + B . + +/*============================================================================== + * GPIO14_IRQHandler + */ + .weak GPIO14_IRQHandler + .type GPIO14_IRQHandler, %function +GPIO14_IRQHandler: + B . + +/*============================================================================== + * GPIO15_IRQHandler + */ + .weak GPIO15_IRQHandler + .type GPIO15_IRQHandler, %function +GPIO15_IRQHandler: + B . + +/*============================================================================== + * GPIO16_IRQHandler + */ + .weak GPIO16_IRQHandler + .type GPIO16_IRQHandler, %function +GPIO16_IRQHandler: + B . + +/*============================================================================== + * GPIO17_IRQHandler + */ + .weak GPIO17_IRQHandler + .type GPIO17_IRQHandler, %function +GPIO17_IRQHandler: + B . + +/*============================================================================== + * GPIO18_IRQHandler + */ + .weak GPIO18_IRQHandler + .type GPIO18_IRQHandler, %function +GPIO18_IRQHandler: + B . + +/*============================================================================== + * GPIO19_IRQHandler + */ + .weak GPIO19_IRQHandler + .type GPIO19_IRQHandler, %function +GPIO19_IRQHandler: + B . + +/*============================================================================== + * GPIO20_IRQHandler + */ + .weak GPIO20_IRQHandler + .type GPIO20_IRQHandler, %function +GPIO20_IRQHandler: + B . + +/*============================================================================== + * GPIO21_IRQHandler + */ + .weak GPIO21_IRQHandler + .type GPIO21_IRQHandler, %function +GPIO21_IRQHandler: + B . + +/*============================================================================== + * GPIO22_IRQHandler + */ + .weak GPIO22_IRQHandler + .type GPIO22_IRQHandler, %function +GPIO22_IRQHandler: + B . + +/*============================================================================== + * GPIO23_IRQHandler + */ + .weak GPIO23_IRQHandler + .type GPIO23_IRQHandler, %function +GPIO23_IRQHandler: + B . + +/*============================================================================== + * GPIO24_IRQHandler + */ + .weak GPIO24_IRQHandler + .type GPIO24_IRQHandler, %function +GPIO24_IRQHandler: + B . + +/*============================================================================== + * GPIO25_IRQHandler + */ + .weak GPIO25_IRQHandler + .type GPIO25_IRQHandler, %function +GPIO25_IRQHandler: + B . + +/*============================================================================== + * GPIO26_IRQHandler + */ + .weak GPIO26_IRQHandler + .type GPIO26_IRQHandler, %function +GPIO26_IRQHandler: + B . + +/*============================================================================== + * GPIO27_IRQHandler + */ + .weak GPIO27_IRQHandler + .type GPIO27_IRQHandler, %function +GPIO27_IRQHandler: + B . + +/*============================================================================== + * GPIO28_IRQHandler + */ + .weak GPIO28_IRQHandler + .type GPIO28_IRQHandler, %function +GPIO28_IRQHandler: + B . + +/*============================================================================== + * GPIO29_IRQHandler + */ + .weak GPIO29_IRQHandler + .type GPIO29_IRQHandler, %function +GPIO29_IRQHandler: + B . + +/*============================================================================== + * GPIO30_IRQHandler + */ + .weak GPIO30_IRQHandler + .type GPIO30_IRQHandler, %function +GPIO30_IRQHandler: + B . + +/*============================================================================== + * GPIO31_IRQHandler + */ + .weak GPIO31_IRQHandler + .type GPIO31_IRQHandler, %function +GPIO31_IRQHandler: + B . + +/*============================================================================== + * ACE_PC0_Flag0_IRQHandler + */ + .weak ACE_PC0_Flag0_IRQHandler + .type ACE_PC0_Flag0_IRQHandler, %function +ACE_PC0_Flag0_IRQHandler: + B . + +/*============================================================================== + * ACE_PC0_Flag1_IRQHandler + */ + .weak ACE_PC0_Flag1_IRQHandler + .type ACE_PC0_Flag1_IRQHandler, %function +ACE_PC0_Flag1_IRQHandler: + B . + +/*============================================================================== + * ACE_PC0_Flag2_IRQHandler + */ + .weak ACE_PC0_Flag2_IRQHandler + .type ACE_PC0_Flag2_IRQHandler, %function +ACE_PC0_Flag2_IRQHandler: + B . + +/*============================================================================== + * ACE_PC0_Flag3_IRQHandler + */ + .weak ACE_PC0_Flag3_IRQHandler + .type ACE_PC0_Flag3_IRQHandler, %function +ACE_PC0_Flag3_IRQHandler: + B . + +/*============================================================================== + * ACE_PC1_Flag0_IRQHandler + */ + .weak ACE_PC1_Flag0_IRQHandler + .type ACE_PC1_Flag0_IRQHandler, %function +ACE_PC1_Flag0_IRQHandler: + B . + +/*============================================================================== + * ACE_PC1_Flag1_IRQHandler + */ + .weak ACE_PC1_Flag1_IRQHandler + .type ACE_PC1_Flag1_IRQHandler, %function +ACE_PC1_Flag1_IRQHandler: + B . + +/*============================================================================== + * ACE_PC1_Flag2_IRQHandler + */ + .weak ACE_PC1_Flag2_IRQHandler + .type ACE_PC1_Flag2_IRQHandler, %function +ACE_PC1_Flag2_IRQHandler: + B . + +/*============================================================================== + * ACE_PC1_Flag3_IRQHandler + */ + .weak ACE_PC1_Flag3_IRQHandler + .type ACE_PC1_Flag3_IRQHandler, %function +ACE_PC1_Flag3_IRQHandler: + B . + +/*============================================================================== + * ACE_PC2_Flag0_IRQHandler + */ + .weak ACE_PC2_Flag0_IRQHandler + .type ACE_PC2_Flag0_IRQHandler, %function +ACE_PC2_Flag0_IRQHandler: + B . + +/*============================================================================== + * ACE_PC2_Flag1_IRQHandler + */ + .weak ACE_PC2_Flag1_IRQHandler + .type ACE_PC2_Flag1_IRQHandler, %function +ACE_PC2_Flag1_IRQHandler: + B . + +/*============================================================================== + * ACE_PC2_Flag2_IRQHandler + */ + .weak ACE_PC2_Flag2_IRQHandler + .type ACE_PC2_Flag2_IRQHandler, %function +ACE_PC2_Flag2_IRQHandler: + B . + +/*============================================================================== + * ACE_PC2_Flag3_IRQHandler + */ + .weak ACE_PC2_Flag3_IRQHandler + .type ACE_PC2_Flag3_IRQHandler, %function +ACE_PC2_Flag3_IRQHandler: + B . + +/*============================================================================== + * ACE_ADC0_DataValid_IRQHandler + */ + .weak ACE_ADC0_DataValid_IRQHandler + .type ACE_ADC0_DataValid_IRQHandler, %function +ACE_ADC0_DataValid_IRQHandler: + B . + +/*============================================================================== + * ACE_ADC1_DataValid_IRQHandler + */ + .weak ACE_ADC1_DataValid_IRQHandler + .type ACE_ADC1_DataValid_IRQHandler, %function +ACE_ADC1_DataValid_IRQHandler: + B . + +/*============================================================================== + * ACE_ADC2_DataValid_IRQHandler + */ + .weak ACE_ADC2_DataValid_IRQHandler + .type ACE_ADC2_DataValid_IRQHandler, %function +ACE_ADC2_DataValid_IRQHandler: + B . + +/*============================================================================== + * ACE_ADC0_CalDone_IRQHandler + */ + .weak ACE_ADC0_CalDone_IRQHandler + .type ACE_ADC0_CalDone_IRQHandler, %function +ACE_ADC0_CalDone_IRQHandler: + B . + +/*============================================================================== + * ACE_ADC1_CalDone_IRQHandler + */ + .weak ACE_ADC1_CalDone_IRQHandler + .type ACE_ADC1_CalDone_IRQHandler, %function +ACE_ADC1_CalDone_IRQHandler: + B . + +/*============================================================================== + * ACE_ADC2_CalDone_IRQHandler + */ + .weak ACE_ADC2_CalDone_IRQHandler + .type ACE_ADC2_CalDone_IRQHandler, %function +ACE_ADC2_CalDone_IRQHandler: + B . + +/*============================================================================== + * ACE_ADC0_CalStart_IRQHandler + */ + .weak ACE_ADC0_CalStart_IRQHandler + .type ACE_ADC0_CalStart_IRQHandler, %function +ACE_ADC0_CalStart_IRQHandler: + B . + +/*============================================================================== + * ACE_ADC1_CalStart_IRQHandler + */ + .weak ACE_ADC1_CalStart_IRQHandler + .type ACE_ADC1_CalStart_IRQHandler, %function +ACE_ADC1_CalStart_IRQHandler: + B . + +/*============================================================================== + * ACE_ADC2_CalStart_IRQHandler + */ + .weak ACE_ADC2_CalStart_IRQHandler + .type ACE_ADC2_CalStart_IRQHandler, %function +ACE_ADC2_CalStart_IRQHandler: + B . + +/*============================================================================== + * ACE_Comp0_Fall_IRQHandler + */ + .weak ACE_Comp0_Fall_IRQHandler + .type ACE_Comp0_Fall_IRQHandler, %function +ACE_Comp0_Fall_IRQHandler: + B . + +/*============================================================================== + * ACE_Comp1_Fall_IRQHandler + */ + .weak ACE_Comp1_Fall_IRQHandler + .type ACE_Comp1_Fall_IRQHandler, %function +ACE_Comp1_Fall_IRQHandler: + B . + +/*============================================================================== + * ACE_Comp2_Fall_IRQHandler + */ + .weak ACE_Comp2_Fall_IRQHandler + .type ACE_Comp2_Fall_IRQHandler, %function +ACE_Comp2_Fall_IRQHandler: + B . + +/*============================================================================== + * ACE_Comp3_Fall_IRQHandler + */ + .weak ACE_Comp3_Fall_IRQHandler + .type ACE_Comp3_Fall_IRQHandler, %function +ACE_Comp3_Fall_IRQHandler: + B . + +/*============================================================================== + * ACE_Comp4_Fall_IRQHandler + */ + .weak ACE_Comp4_Fall_IRQHandler + .type ACE_Comp4_Fall_IRQHandler, %function +ACE_Comp4_Fall_IRQHandler: + B . + +/*============================================================================== + * ACE_Comp5_Fall_IRQHandler + */ + .weak ACE_Comp5_Fall_IRQHandler + .type ACE_Comp5_Fall_IRQHandler, %function +ACE_Comp5_Fall_IRQHandler: + B . + +/*============================================================================== + * ACE_Comp6_Fall_IRQHandler + */ + .weak ACE_Comp6_Fall_IRQHandler + .type ACE_Comp6_Fall_IRQHandler, %function +ACE_Comp6_Fall_IRQHandler: + B . + +/*============================================================================== + * ACE_Comp7_Fall_IRQHandler + */ + .weak ACE_Comp7_Fall_IRQHandler + .type ACE_Comp7_Fall_IRQHandler, %function +ACE_Comp7_Fall_IRQHandler: + B . + +/*============================================================================== + * ACE_Comp8_Fall_IRQHandler + */ + .weak ACE_Comp8_Fall_IRQHandler + .type ACE_Comp8_Fall_IRQHandler, %function +ACE_Comp8_Fall_IRQHandler: + B . + +/*============================================================================== + * ACE_Comp9_Fall_IRQHandler + */ + .weak ACE_Comp9_Fall_IRQHandler + .type ACE_Comp9_Fall_IRQHandler, %function +ACE_Comp9_Fall_IRQHandler: + B . + +/*============================================================================== + * ACE_Comp10_Fall_IRQHandler + */ + .weak ACE_Comp10_Fall_IRQHandler + .type ACE_Comp10_Fall_IRQHandler, %function +ACE_Comp10_Fall_IRQHandler: + B . + +/*============================================================================== + * ACE_Comp11_Fall_IRQHandler + */ + .weak ACE_Comp11_Fall_IRQHandler + .type ACE_Comp11_Fall_IRQHandler, %function +ACE_Comp11_Fall_IRQHandler: + B . + +/*============================================================================== + * ACE_Comp0_Rise_IRQHandler + */ + .weak ACE_Comp0_Rise_IRQHandler + .type ACE_Comp0_Rise_IRQHandler, %function +ACE_Comp0_Rise_IRQHandler: + B . + +/*============================================================================== + * ACE_Comp1_Rise_IRQHandler + */ + .weak ACE_Comp1_Rise_IRQHandler + .type ACE_Comp1_Rise_IRQHandler, %function +ACE_Comp1_Rise_IRQHandler: + B . + +/*============================================================================== + * ACE_Comp2_Rise_IRQHandler + */ + .weak ACE_Comp2_Rise_IRQHandler + .type ACE_Comp2_Rise_IRQHandler, %function +ACE_Comp2_Rise_IRQHandler: + B . + +/*============================================================================== + * ACE_Comp3_Rise_IRQHandler + */ + .weak ACE_Comp3_Rise_IRQHandler + .type ACE_Comp3_Rise_IRQHandler, %function +ACE_Comp3_Rise_IRQHandler: + B . + +/*============================================================================== + * ACE_Comp4_Rise_IRQHandler + */ + .weak ACE_Comp4_Rise_IRQHandler + .type ACE_Comp4_Rise_IRQHandler, %function +ACE_Comp4_Rise_IRQHandler: + B . + +/*============================================================================== + * ACE_Comp5_Rise_IRQHandler + */ + .weak ACE_Comp5_Rise_IRQHandler + .type ACE_Comp5_Rise_IRQHandler, %function +ACE_Comp5_Rise_IRQHandler: + B . + +/*============================================================================== + * ACE_Comp6_Rise_IRQHandler + */ + .weak ACE_Comp6_Rise_IRQHandler + .type ACE_Comp6_Rise_IRQHandler, %function +ACE_Comp6_Rise_IRQHandler: + B . + +/*============================================================================== + * ACE_Comp7_Rise_IRQHandler + */ + .weak ACE_Comp7_Rise_IRQHandler + .type ACE_Comp7_Rise_IRQHandler, %function +ACE_Comp7_Rise_IRQHandler: + B . + +/*============================================================================== + * ACE_Comp8_Rise_IRQHandler + */ + .weak ACE_Comp8_Rise_IRQHandler + .type ACE_Comp8_Rise_IRQHandler, %function +ACE_Comp8_Rise_IRQHandler: + B . + +/*============================================================================== + * ACE_Comp9_Rise_IRQHandler + */ + .weak ACE_Comp9_Rise_IRQHandler + .type ACE_Comp9_Rise_IRQHandler, %function +ACE_Comp9_Rise_IRQHandler: + B . + +/*============================================================================== + * ACE_Comp10_Rise_IRQHandler + */ + .weak ACE_Comp10_Rise_IRQHandler + .type ACE_Comp10_Rise_IRQHandler, %function +ACE_Comp10_Rise_IRQHandler: + B . + +/*============================================================================== + * ACE_Comp11_Rise_IRQHandler + */ + .weak ACE_Comp11_Rise_IRQHandler + .type ACE_Comp11_Rise_IRQHandler, %function +ACE_Comp11_Rise_IRQHandler: + B . + +/*============================================================================== + * ACE_ADC0_FifoFull_IRQHandler + */ + .weak ACE_ADC0_FifoFull_IRQHandler + .type ACE_ADC0_FifoFull_IRQHandler, %function +ACE_ADC0_FifoFull_IRQHandler: + B . + +/*============================================================================== + * ACE_ADC0_FifoAFull_IRQHandler + */ + .weak ACE_ADC0_FifoAFull_IRQHandler + .type ACE_ADC0_FifoAFull_IRQHandler, %function +ACE_ADC0_FifoAFull_IRQHandler: + B . + +/*============================================================================== + * ACE_ADC0_FifoEmpty_IRQHandler + */ + .weak ACE_ADC0_FifoEmpty_IRQHandler + .type ACE_ADC0_FifoEmpty_IRQHandler, %function +ACE_ADC0_FifoEmpty_IRQHandler: + B . + +/*============================================================================== + * ACE_ADC1_FifoFull_IRQHandler + */ + .weak ACE_ADC1_FifoFull_IRQHandler + .type ACE_ADC1_FifoFull_IRQHandler, %function +ACE_ADC1_FifoFull_IRQHandler: + B . + +/*============================================================================== + * ACE_ADC1_FifoAFull_IRQHandler + */ + .weak ACE_ADC1_FifoAFull_IRQHandler + .type ACE_ADC1_FifoAFull_IRQHandler, %function +ACE_ADC1_FifoAFull_IRQHandler: + B . + +/*============================================================================== + * ACE_ADC1_FifoEmpty_IRQHandler + */ + .weak ACE_ADC1_FifoEmpty_IRQHandler + .type ACE_ADC1_FifoEmpty_IRQHandler, %function +ACE_ADC1_FifoEmpty_IRQHandler: + B . + +/*============================================================================== + * ACE_ADC2_FifoFull_IRQHandler + */ + .weak ACE_ADC2_FifoFull_IRQHandler + .type ACE_ADC2_FifoFull_IRQHandler, %function +ACE_ADC2_FifoFull_IRQHandler: + B . + +/*============================================================================== + * ACE_ADC2_FifoAFull_IRQHandler + */ + .weak ACE_ADC2_FifoAFull_IRQHandler + .type ACE_ADC2_FifoAFull_IRQHandler, %function +ACE_ADC2_FifoAFull_IRQHandler: + B . + +/*============================================================================== + * ACE_ADC2_FifoEmpty_IRQHandler + */ + .weak ACE_ADC2_FifoEmpty_IRQHandler + .type ACE_ADC2_FifoEmpty_IRQHandler, %function +ACE_ADC2_FifoEmpty_IRQHandler: + B . + +/*============================================================================== + * ACE_PPE_Flag0_IRQHandler + */ + .weak ACE_PPE_Flag0_IRQHandler + .type ACE_PPE_Flag0_IRQHandler, %function +ACE_PPE_Flag0_IRQHandler: + B . + +/*============================================================================== + * ACE_PPE_Flag1_IRQHandler + */ + .weak ACE_PPE_Flag1_IRQHandler + .type ACE_PPE_Flag1_IRQHandler, %function +ACE_PPE_Flag1_IRQHandler: + B . + +/*============================================================================== + * ACE_PPE_Flag2_IRQHandler + */ + .weak ACE_PPE_Flag2_IRQHandler + .type ACE_PPE_Flag2_IRQHandler, %function +ACE_PPE_Flag2_IRQHandler: + B . + +/*============================================================================== + * ACE_PPE_Flag3_IRQHandler + */ + .weak ACE_PPE_Flag3_IRQHandler + .type ACE_PPE_Flag3_IRQHandler, %function +ACE_PPE_Flag3_IRQHandler: + B . + +/*============================================================================== + * ACE_PPE_Flag4_IRQHandler + */ + .weak ACE_PPE_Flag4_IRQHandler + .type ACE_PPE_Flag4_IRQHandler, %function +ACE_PPE_Flag4_IRQHandler: + B . + +/*============================================================================== + * ACE_PPE_Flag5_IRQHandler + */ + .weak ACE_PPE_Flag5_IRQHandler + .type ACE_PPE_Flag5_IRQHandler, %function +ACE_PPE_Flag5_IRQHandler: + B . + +/*============================================================================== + * ACE_PPE_Flag6_IRQHandler + */ + .weak ACE_PPE_Flag6_IRQHandler + .type ACE_PPE_Flag6_IRQHandler, %function +ACE_PPE_Flag6_IRQHandler: + B . + +/*============================================================================== + * ACE_PPE_Flag7_IRQHandler + */ + .weak ACE_PPE_Flag7_IRQHandler + .type ACE_PPE_Flag7_IRQHandler, %function +ACE_PPE_Flag7_IRQHandler: + B . + +/*============================================================================== + * ACE_PPE_Flag8_IRQHandler + */ + .weak ACE_PPE_Flag8_IRQHandler + .type ACE_PPE_Flag8_IRQHandler, %function +ACE_PPE_Flag8_IRQHandler: + B . + +/*============================================================================== + * ACE_PPE_Flag9_IRQHandler + */ + .weak ACE_PPE_Flag9_IRQHandler + .type ACE_PPE_Flag9_IRQHandler, %function +ACE_PPE_Flag9_IRQHandler: + B . + +/*============================================================================== + * ACE_PPE_Flag10_IRQHandler + */ + .weak ACE_PPE_Flag10_IRQHandler + .type ACE_PPE_Flag10_IRQHandler, %function +ACE_PPE_Flag10_IRQHandler: + B . + +/*============================================================================== + * ACE_PPE_Flag11_IRQHandler + */ + .weak ACE_PPE_Flag11_IRQHandler + .type ACE_PPE_Flag11_IRQHandler, %function +ACE_PPE_Flag11_IRQHandler: + B . + +/*============================================================================== + * ACE_PPE_Flag12_IRQHandler + */ + .weak ACE_PPE_Flag12_IRQHandler + .type ACE_PPE_Flag12_IRQHandler, %function +ACE_PPE_Flag12_IRQHandler: + B . + +/*============================================================================== + * ACE_PPE_Flag13_IRQHandler + */ + .weak ACE_PPE_Flag13_IRQHandler + .type ACE_PPE_Flag13_IRQHandler, %function +ACE_PPE_Flag13_IRQHandler: + B . + +/*============================================================================== + * ACE_PPE_Flag14_IRQHandler + */ + .weak ACE_PPE_Flag14_IRQHandler + .type ACE_PPE_Flag14_IRQHandler, %function +ACE_PPE_Flag14_IRQHandler: + B . + +/*============================================================================== + * ACE_PPE_Flag15_IRQHandler + */ + .weak ACE_PPE_Flag15_IRQHandler + .type ACE_PPE_Flag15_IRQHandler, %function +ACE_PPE_Flag15_IRQHandler: + B . + +/*============================================================================== + * ACE_PPE_Flag16_IRQHandler + */ + .weak ACE_PPE_Flag16_IRQHandler + .type ACE_PPE_Flag16_IRQHandler, %function +ACE_PPE_Flag16_IRQHandler: + B . + +/*============================================================================== + * ACE_PPE_Flag17_IRQHandler + */ + .weak ACE_PPE_Flag17_IRQHandler + .type ACE_PPE_Flag17_IRQHandler, %function +ACE_PPE_Flag17_IRQHandler: + B . + +/*============================================================================== + * ACE_PPE_Flag18_IRQHandler + */ + .weak ACE_PPE_Flag18_IRQHandler + .type ACE_PPE_Flag18_IRQHandler, %function +ACE_PPE_Flag18_IRQHandler: + B . + +/*============================================================================== + * ACE_PPE_Flag19_IRQHandler + */ + .weak ACE_PPE_Flag19_IRQHandler + .type ACE_PPE_Flag19_IRQHandler, %function +ACE_PPE_Flag19_IRQHandler: + B . + +/*============================================================================== + * ACE_PPE_Flag20_IRQHandler + */ + .weak ACE_PPE_Flag20_IRQHandler + .type ACE_PPE_Flag20_IRQHandler, %function +ACE_PPE_Flag20_IRQHandler: + B . + +/*============================================================================== + * ACE_PPE_Flag21_IRQHandler + */ + .weak ACE_PPE_Flag21_IRQHandler + .type ACE_PPE_Flag21_IRQHandler, %function +ACE_PPE_Flag21_IRQHandler: + B . + +/*============================================================================== + * ACE_PPE_Flag22_IRQHandler + */ + .weak ACE_PPE_Flag22_IRQHandler + .type ACE_PPE_Flag22_IRQHandler, %function +ACE_PPE_Flag22_IRQHandler: + B . + +/*============================================================================== + * ACE_PPE_Flag23_IRQHandler + */ + .weak ACE_PPE_Flag23_IRQHandler + .type ACE_PPE_Flag23_IRQHandler, %function +ACE_PPE_Flag23_IRQHandler: + B . + +/*============================================================================== + * ACE_PPE_Flag24_IRQHandler + */ + .weak ACE_PPE_Flag24_IRQHandler + .type ACE_PPE_Flag24_IRQHandler, %function +ACE_PPE_Flag24_IRQHandler: + B . + +/*============================================================================== + * ACE_PPE_Flag25_IRQHandler + */ + .weak ACE_PPE_Flag25_IRQHandler + .type ACE_PPE_Flag25_IRQHandler, %function +ACE_PPE_Flag25_IRQHandler: + B . + +/*============================================================================== + * ACE_PPE_Flag26_IRQHandler + */ + .weak ACE_PPE_Flag26_IRQHandler + .type ACE_PPE_Flag26_IRQHandler, %function +ACE_PPE_Flag26_IRQHandler: + B . + +/*============================================================================== + * ACE_PPE_Flag27_IRQHandler + */ + .weak ACE_PPE_Flag27_IRQHandler + .type ACE_PPE_Flag27_IRQHandler, %function +ACE_PPE_Flag27_IRQHandler: + B . + +/*============================================================================== + * ACE_PPE_Flag28_IRQHandler + */ + .weak ACE_PPE_Flag28_IRQHandler + .type ACE_PPE_Flag28_IRQHandler, %function +ACE_PPE_Flag28_IRQHandler: + B . + +/*============================================================================== + * ACE_PPE_Flag29_IRQHandler + */ + .weak ACE_PPE_Flag29_IRQHandler + .type ACE_PPE_Flag29_IRQHandler, %function +ACE_PPE_Flag29_IRQHandler: + B . + +/*============================================================================== + * ACE_PPE_Flag30_IRQHandler + */ + .weak ACE_PPE_Flag30_IRQHandler + .type ACE_PPE_Flag30_IRQHandler, %function +ACE_PPE_Flag30_IRQHandler: + B . + +/*============================================================================== + * ACE_PPE_Flag31_IRQHandler + */ + .weak ACE_PPE_Flag31_IRQHandler + .type ACE_PPE_Flag31_IRQHandler, %function +ACE_PPE_Flag31_IRQHandler: + B . + +.end diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/system_a2fxxxm3.c b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/system_a2fxxxm3.c new file mode 100644 index 000000000..1b3798f3e --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/system_a2fxxxm3.c @@ -0,0 +1,199 @@ +/******************************************************************************* + * (c) Copyright 2009 Actel Corporation. All rights reserved. + * + * SmartFusion A2FxxxM3 CMSIS system initialization. + * + * SVN $Revision: 2069 $ + * SVN $Date: 2010-01-28 00:23:48 +0000 (Thu, 28 Jan 2010) $ + */ +#include "a2fxxxm3.h" +#include "mss_assert.h" + +/* System frequency (FCLK) coming out of reset is 25MHz. */ +#define RESET_SYSCLCK_FREQ 25000000uL + +/* + * SmartFusion Microcontroller Subsystem FLCK frequency. + * The value of SMARTFUSION_FCLK_FREQ is used to report the system's clock + * frequency in system's which either do not use the Actel System Boot or + * a version of the Actel System Boot older than 1.3.1. In eitehr of these cases + * SMARTFUSION_FCLK_FREQ should be defined in the projects settings to reflect + * the FCLK frequency selected in the Libero MSS configurator. + * Systems using the Actel System Boot version 1.3.1 or later do not require this + * define since the system's frequency is retrieved from eNVM spare pages where + * the MSS Configurator stored the frequency selected during hardware design/configuration. + */ +#ifdef SMARTFUSION_FCLK_FREQ +#define SMARTFUSION_FCLK_FREQ_DEFINED 1 +#else +#define SMARTFUSION_FCLK_FREQ_DEFINED 0 +#define SMARTFUSION_FCLK_FREQ RESET_SYSCLCK_FREQ +#endif + +/* Divider values for APB0, APB1 and ACE clocks. */ +#define RESET_PCLK0_DIV 4uL +#define RESET_PCLK1_DIV 4uL +#define RESET_ACE_DIV 4uL +#define RESET_FPGA_CLK_DIV 4uL + +/* System register clock control mask and shift for PCLK dividers. */ +#define PCLK_DIV_MASK 0x00000003uL +#define PCLK0_DIV_SHIFT 2uL +#define PCLK1_DIV_SHIFT 4uL +#define ACE_DIV_SHIFT 6uL + +/* System register MSS_CCC_DIV_CR mask and shift for GLB (FPGA fabric clock). */ +#define OBDIV_SHIFT 8uL +#define OBDIV_MASK 0x0000001FuL +#define OBDIVHALF_SHIFT 13uL +#define OBDIVHALF_MASK 0x00000001uL + +/* + * Actel system boot version defines used to extract the system clock from eNVM + * spare pages. + * These defines allow detecting the presence of Actel system boot in eNVM spare + * pages and the version of that system boot executable and associated + * configuration data. + */ +#define SYSBOOT_KEY_ADDR (uint32_t *)0x6008081C +#define SYSBOOT_KEY_VALUE 0x4C544341uL +#define SYSBOOT_VERSION_ADDR (uint32_t *)0x60080840 +#define SYSBOOT_1_3_FCLK_ADDR (uint32_t *)0x6008162C +#define SYSBOOT_2_x_FCLK_ADDR (uint32_t *)0x60081EAC + +/* + * The system boot version is stored in the least significant 24 bits of a word. + * The FCLK is stored in eNVM from version 1.3.1 of the system boot. We expect + * that the major version number of the system boot version will change if the + * system boot configuration data layout needs to change. + */ +#define SYSBOOT_VERSION_MASK 0x00FFFFFFuL +#define MIN_SYSBOOT_VERSION 0x00010301uL +#define SYSBOOT_VERSION_2_X 0x00020000uL +#define MAX_SYSBOOT_VERSION 0x00030000uL + +/* Standard CMSIS global variables. */ +uint32_t SystemFrequency = SMARTFUSION_FCLK_FREQ; /*!< System Clock Frequency (Core Clock) */ +uint32_t SystemCoreClock = SMARTFUSION_FCLK_FREQ; /*!< System Clock Frequency (Core Clock) */ + +/* SmartFusion specific clocks. */ +uint32_t g_FrequencyPCLK0 = (SMARTFUSION_FCLK_FREQ / RESET_PCLK0_DIV); /*!< Clock frequency of APB bus 0. */ +uint32_t g_FrequencyPCLK1 = (SMARTFUSION_FCLK_FREQ / RESET_PCLK1_DIV); /*!< Clock frequency of APB bus 1. */ +uint32_t g_FrequencyACE = (SMARTFUSION_FCLK_FREQ / RESET_ACE_DIV); /*!< Clock frequency of Analog Compute Engine. */ +uint32_t g_FrequencyFPGA = (SMARTFUSION_FCLK_FREQ / RESET_FPGA_CLK_DIV); /*!< Clock frequecny of FPGA fabric */ + +/* Local functions */ +static uint32_t GetSystemClock( void ); + +/***************************************************************************//** + * See system_a2fm3fxxx.h for details. + */ +void SystemInit(void) +{ +} + +/***************************************************************************//** + * + */ +void SystemCoreClockUpdate (void) +{ + uint32_t PclkDiv0; + uint32_t PclkDiv1; + uint32_t AceDiv; + uint32_t FabDiv; + + const uint32_t pclk_div_lut[4] = { 1uL, 2uL, 4uL, 1uL }; + + /* Read PCLK dividers from system registers. Multiply the value read from + * system register by two to get actual divider value. */ + PclkDiv0 = pclk_div_lut[((SYSREG->MSS_CLK_CR >> PCLK0_DIV_SHIFT) & PCLK_DIV_MASK)]; + PclkDiv1 = pclk_div_lut[((SYSREG->MSS_CLK_CR >> PCLK1_DIV_SHIFT) & PCLK_DIV_MASK)]; + AceDiv = pclk_div_lut[((SYSREG->MSS_CLK_CR >> ACE_DIV_SHIFT) & PCLK_DIV_MASK)]; + { + /* Compute the FPGA fabric frequency divider. */ + uint32_t obdiv; + uint32_t obdivhalf; + + obdiv = (SYSREG->MSS_CCC_DIV_CR >> OBDIV_SHIFT) & OBDIV_MASK; + obdivhalf = (SYSREG->MSS_CCC_DIV_CR >> OBDIVHALF_SHIFT) & OBDIVHALF_MASK; + FabDiv = obdiv + 1uL; + if ( obdivhalf != 0uL ) + { + FabDiv = FabDiv * 2uL; + } + } + + /* Retrieve FCLK from eNVM spare pages if Actel system boot programmed as part of the system. */ + + /* Read system clock from eNVM spare pages. */ + SystemCoreClock = GetSystemClock(); + g_FrequencyPCLK0 = SystemCoreClock / PclkDiv0; + g_FrequencyPCLK1 = SystemCoreClock / PclkDiv1; + g_FrequencyACE = SystemCoreClock / AceDiv; + g_FrequencyFPGA = SystemCoreClock / FabDiv; + + /* Keep SystemFrequency as well as SystemCoreClock for legacy reasons. */ + SystemFrequency = SystemCoreClock; +} + +/***************************************************************************//** + * Retrieve the system clock frequency from eNVM spare page if available. + * Returns the frequency defined through SMARTFUSION_FCLK_FREQ if FCLK cannot be + * retrieved from eNVM spare pages. + * The FCLK frequency value selected in the MSS Configurator software tool is + * stored in eNVM spare pages as part of the Actel system boot configuration data. + */ +uint32_t GetSystemClock( void ) +{ + uint32_t fclk = 0uL; + + uint32_t * p_sysboot_key = SYSBOOT_KEY_ADDR; + + if ( SYSBOOT_KEY_VALUE == *p_sysboot_key ) + { + /* Actel system boot programmed, check if it has the FCLK value stored. */ + uint32_t *p_sysboot_version = SYSBOOT_VERSION_ADDR; + uint32_t sysboot_version = *p_sysboot_version; + + sysboot_version &= SYSBOOT_VERSION_MASK; + + if ( sysboot_version >= MIN_SYSBOOT_VERSION ) + { + /* Handle change of eNVM location of FCLK between 1.3.x and 2.x.x versions of the system boot. */ + if ( sysboot_version < SYSBOOT_VERSION_2_X ) + { + /* Read FCLK value from MSS configurator generated configuration + * data stored in eNVM spare pages as part of system boot version 1.3.x + * configuration tables. */ + uint32_t *p_fclk = SYSBOOT_1_3_FCLK_ADDR; + fclk = *p_fclk; + } + else if ( sysboot_version < MAX_SYSBOOT_VERSION ) + { + /* Read FCLK value from MSS configurator generated configuration + * data stored in eNVM spare pages as part of system boot version 2.x.x + * configuration tables. */ + uint32_t *p_fclk = SYSBOOT_2_x_FCLK_ADDR; + fclk = *p_fclk; + } + else + { + fclk = 0uL; + } + } + } + + if ( 0uL == fclk ) + { + /* + * Could not retrieve FCLK from system boot configuration data. Fall back + * to using SMARTFUSION_FCLK_FREQ which must then be defined as part of + * project settings. + */ + ASSERT( SMARTFUSION_FCLK_FREQ_DEFINED ); + fclk = SMARTFUSION_FCLK_FREQ; + } + + return fclk; +} + diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/system_a2fxxxm3.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/system_a2fxxxm3.h new file mode 100644 index 000000000..6ae0ad5b7 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/CMSIS/system_a2fxxxm3.h @@ -0,0 +1,49 @@ +/******************************************************************************* + * (c) Copyright 2009 Actel Corporation. All rights reserved. + * + * SmartFusion A2FxxxM3 CMSIS system initialization. + * + * SVN $Revision: 2064 $ + * SVN $Date: 2010-01-27 15:05:58 +0000 (Wed, 27 Jan 2010) $ + */ + +#ifndef __SYSTEM_A2FM3FXX_H__ +#define __SYSTEM_A2FM3FXX_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Standard CMSIS global variables. */ +extern uint32_t SystemFrequency; /*!< System Clock Frequency (Core Clock) */ +extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ + +/* SmartFusion specific clocks. */ +extern uint32_t g_FrequencyPCLK0; /*!< Clock frequency of APB bus 0. */ +extern uint32_t g_FrequencyPCLK1; /*!< Clock frequency of APB bus 1. */ +extern uint32_t g_FrequencyACE; /*!< Clock frequency of Analog Compute Engine. */ +extern uint32_t g_FrequencyFPGA; /*!< Clock frequecny of FPGA fabric */ + +/***************************************************************************//** + * The SystemInit() is a standard CMSIS function called during system startup. + * It is meant to perform low level hardware setup such as configuring PLLs. In + * the case of SmartFusion these hardware setup operations are performed by the + * chip boot which executed before the application started. Therefore this + * function does not need to perform any hardware setup. + */ +void SystemInit(void); + +/***************************************************************************//** + * The SystemCoreClockUpdate() is a standard CMSIS function which can be called + * by the application in order to ensure that the SystemCoreClock global + * variable contains the up to date Cortex-M3 core frequency. Calling this + * function also updates the global variables containing the frequencies of the + * APB busses connecting the peripherals and the ACE frequency. + */ +void SystemCoreClockUpdate(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/I2C/i2c.c b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/I2C/i2c.c new file mode 100644 index 000000000..46dbf6217 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/I2C/i2c.c @@ -0,0 +1,798 @@ +/******************************************************************************* + * (c) Copyright 2007-2008 Actel Corporation. All rights reserved. + * + * SmartFusion microcontroller subsystem I2C bare metal software driver + * implementation. + * + * SVN $Revision: 2152 $ + * SVN $Date: 2010-02-11 14:44:11 +0000 (Thu, 11 Feb 2010) $ + */ +#include "i2c.h" +#include "../../CMSIS/mss_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*------------------------------------------------------------------------------ + * I2C transaction direction. + */ +#define WRITE_DIR 0 +#define READ_DIR 1 + +/* -- TRANSACTIONS TYPES -- */ +#define NO_TRANSACTION 0 +#define MASTER_WRITE_TRANSACTION 1 +#define MASTER_READ_TRANSACTION 2 +#define MASTER_RANDOM_READ_TRANSACTION 3 +#define WRITE_SLAVE_TRANSACTION 4 +#define READ_SLAVE_TRANSACTION 5 +#define RANDOM_READ_SLAVE_TRANSACTION 6 + + +/* -- SMBUS H/W STATES -- */ +/* -- MASTER STATES -- */ +#define ST_START 0x08 /* start condition sent */ +#define ST_RESTART 0x10 /* repeated start */ +#define ST_SLAW_ACK 0x18 /* SLA+W sent, ack received */ +#define ST_SLAW_NACK 0x20 /* SLA+W sent, nack received */ +#define ST_TX_DATA_ACK 0x28 /* Data sent, ACK'ed */ +#define ST_TX_DATA_NACK 0x30 /* Data sent, NACK'ed */ +#define ST_LOST_ARB 0x38 /* Master lost arbitration */ +#define ST_SLAR_ACK 0x40 /* SLA+R sent, ACK'ed */ +#define ST_SLAR_NACK 0x48 /* SLA+R sent, NACK'ed */ +#define ST_RX_DATA_ACK 0x50 /* Data received, ACK sent */ +#define ST_RX_DATA_NACK 0x58 /* Data received, NACK sent */ + +/* -- SLAVE STATES -- */ +#define ST_SLAVE_SLAW 0x60 /* SLA+W received */ +#define ST_SLAVE_SLAR_ACK 0xA8 /* SLA+R received, ACK returned */ +#define ST_SLV_LA 0x68 /* Slave lost arbitration */ +#define ST_GCA 0x70 /* GCA received */ +#define ST_GCA_LA 0x78 /* GCA lost arbitration */ +#define ST_RDATA 0x80 /* Data received */ +#define ST_SLA_NACK 0x88 /* Slave addressed, NACK returned */ +#define ST_GCA_ACK 0x90 /* Previously addresses with GCA, data ACKed */ +#define ST_GCA_NACK 0x98 /* GCA addressed, NACK returned */ +#define ST_RSTOP 0xA0 /* Stop received */ +#define ST_REPEAT 0xA0 /* Repeated start received */ +#define ST_SLAR_ACKS 0xA8 /* Slave read received, ACKed */ +#define ST_SLARW_LA 0xB0 /* Arbitration lost */ +#define ST_RACK 0xB8 /* Byte sent, ACK received */ +#define ST_SLAVE_RNACK 0xC0 /* Byte sent, NACK received */ +#define ST_FINAL 0xC8 /* Final byte sent, ACK received */ +#define ST_BERR 0x00 /* Error on the bus */ +#define ST_SLV_RST 0xD8 /* Slave reset state */ + +/*------------------------------------------------------------------------------ + * + */ +static uint32_t disable_interrupts( void ); +static void restore_interrupts( uint32_t primask ); +static void mss_i2c_isr( mss_i2c_instance_t * this_i2c ); + +/*------------------------------------------------------------------------------ + * + *------------------------------------------------------------------------------ + * + */ +mss_i2c_instance_t g_mss_i2c0; +mss_i2c_instance_t g_mss_i2c1; + +/*------------------------------------------------------------------------------ + * MSS_I2C_init() + * See "mss_i2c.h" for details of how to use this function. + */ +void MSS_I2C_init +( + mss_i2c_instance_t * this_i2c, + uint8_t ser_address, + mss_i2c_clock_divider_t ser_clock_speed +) +{ + uint_fast16_t clock_speed = ser_clock_speed; + + ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) ); + + if ( this_i2c == &g_mss_i2c0 ) + { + this_i2c->irqn = I2C0_IRQn; + this_i2c->hw_reg = I2C0; + this_i2c->hw_reg_bit = I2C0_BITBAND; + + /* reset I2C0 */ + SYSREG->SOFT_RST_CR |= SYSREG_I2C0_SOFTRESET_MASK; + /* Clear any previously pended I2C0 interrupt */ + NVIC_ClearPendingIRQ( I2C0_IRQn ); + /* Take I2C0 out of reset. */ + SYSREG->SOFT_RST_CR &= ~SYSREG_I2C0_SOFTRESET_MASK; + } + else + { + this_i2c->irqn = I2C1_IRQn; + this_i2c->hw_reg = I2C1; + this_i2c->hw_reg_bit = I2C1_BITBAND; + + /* reset I2C1 */ + SYSREG->SOFT_RST_CR |= SYSREG_I2C1_SOFTRESET_MASK; + /* Clear any previously pended I2C1 interrupt */ + NVIC_ClearPendingIRQ( I2C1_IRQn ); + /* Take I2C1 out of reset. */ + SYSREG->SOFT_RST_CR &= ~SYSREG_I2C1_SOFTRESET_MASK; + } + + this_i2c->transaction = NO_TRANSACTION; + + this_i2c->ser_address = ser_address; + + this_i2c->tx_buffer = 0; + this_i2c->tx_size = 0; + this_i2c->tx_idx = 0; + + this_i2c->rx_buffer = 0; + this_i2c->rx_size = 0; + this_i2c->rx_idx = 0; + + this_i2c->status = MSS_I2C_SUCCESS; + + this_i2c->random_read_addr = 0; + + this_i2c->slave_write_handler = 0; + this_i2c->slave_mem_offset_length = 0; + + this_i2c->hw_reg_bit->CTRL_ENS1 = 0x01; /* set enable bit */ + this_i2c->hw_reg_bit->CTRL_CR2 = (clock_speed >> 2) & 0x01; + this_i2c->hw_reg_bit->CTRL_CR1 = (clock_speed >> 1) & 0x01; + this_i2c->hw_reg_bit->CTRL_CR0 = clock_speed & 0x01; + this_i2c->hw_reg->ADDR = this_i2c->ser_address; +} + +/*------------------------------------------------------------------------------ + * MSS_I2C_set_slave_mem_offset_length() + * See "mss_i2c.h" for details of how to use this function. + */ +void MSS_I2C_set_slave_mem_offset_length +( + mss_i2c_instance_t * this_i2c, + uint8_t offset_length +) +{ + ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) ); + + this_i2c->slave_mem_offset_length = offset_length; +} + +/*------------------------------------------------------------------------------ + * MSS_I2C_register_write_handler() + * See "mss_i2c.h" for details of how to use this function. + */ +void MSS_I2C_register_write_handler +( + mss_i2c_instance_t * this_i2c, + mss_i2c_slave_wr_handler_t handler +) +{ + ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) ); + + this_i2c->slave_write_handler = handler; +} + +/*------------------------------------------------------------------------------ + * MSS_I2C_write() + * See "mss_i2c.h" for details of how to use this function. + */ +void MSS_I2C_write +( + mss_i2c_instance_t * this_i2c, + uint8_t serial_addr, + const uint8_t * write_buffer, + uint16_t write_size, + uint8_t options +) +{ + volatile uint8_t stat_ctrl; + uint8_t serial_interrupt; + + uint32_t primask; + + ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) ); + + primask = disable_interrupts(); + + this_i2c->transaction = MASTER_WRITE_TRANSACTION; + + this_i2c->target_addr = serial_addr; + this_i2c->dir = WRITE_DIR; + this_i2c->tx_buffer = write_buffer; + this_i2c->tx_size = write_size; + this_i2c->tx_idx = 0; + + this_i2c->status = MSS_I2C_IN_PROGRESS; + this_i2c->options = options; + + /* Clear interrupts if required (depends on repeated starts).*/ + serial_interrupt = this_i2c->hw_reg_bit->CTRL_SI; + this_i2c->hw_reg_bit->CTRL_STA = 0x01; + + if ( serial_interrupt != 0 ) + { + this_i2c->hw_reg_bit->CTRL_SI = 0x00; + NVIC_ClearPendingIRQ( this_i2c->irqn ); + } + + stat_ctrl = this_i2c->hw_reg->STATUS; + + NVIC_EnableIRQ( this_i2c->irqn ); + + restore_interrupts( primask ); +} + +/*------------------------------------------------------------------------------ + * MSS_I2C_read() + * See "mss_i2c.h" for details of how to use this function. + */ +void MSS_I2C_read +( + mss_i2c_instance_t * this_i2c, + uint8_t serial_addr, + uint8_t * read_buffer, + uint16_t read_size, + uint8_t options +) +{ + uint32_t primask; + + ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) ); + + if ( read_size > 0 ) + { + volatile uint8_t stat_ctrl; + uint8_t serial_interrupt; + + primask = disable_interrupts(); + + this_i2c->transaction = MASTER_READ_TRANSACTION; + + this_i2c->target_addr = serial_addr; + this_i2c->dir = READ_DIR; + this_i2c->rx_buffer = read_buffer; + this_i2c->rx_size = read_size; + this_i2c->rx_idx = 0; + + this_i2c->status = MSS_I2C_IN_PROGRESS; + + this_i2c->options = options; + + /* Clear interrupts if required (depends on repeated starts).*/ + serial_interrupt = this_i2c->hw_reg_bit->CTRL_SI; + this_i2c->hw_reg_bit->CTRL_STA = 0x01; + + if ( serial_interrupt != 0 ) + { + this_i2c->hw_reg_bit->CTRL_SI = 0x00; + NVIC_ClearPendingIRQ( this_i2c->irqn ); + } + + stat_ctrl = this_i2c->hw_reg->STATUS; + + NVIC_EnableIRQ( this_i2c->irqn ); + + restore_interrupts( primask ); + } +} + +/*------------------------------------------------------------------------------ + * MSS_I2C_write_read() + * See "mss_i2c.h" for details of how to use this function. + */ +void MSS_I2C_write_read +( + mss_i2c_instance_t * this_i2c, + uint8_t serial_addr, + const uint8_t * addr_offset, + uint16_t offset_size, + uint8_t * read_buffer, + uint16_t read_size, + uint8_t options +) +{ + volatile uint8_t stat_ctrl; + uint8_t serial_interrupt; + uint32_t primask; + + ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) ); + + primask = disable_interrupts(); + + this_i2c->transaction = MASTER_RANDOM_READ_TRANSACTION; + this_i2c->target_addr = serial_addr; + this_i2c->dir = WRITE_DIR; + this_i2c->tx_buffer = addr_offset; + this_i2c->tx_size = offset_size; + this_i2c->tx_idx = 0; + + this_i2c->rx_buffer = read_buffer; + this_i2c->rx_size = read_size; + this_i2c->rx_idx = 0; + + this_i2c->status = MSS_I2C_IN_PROGRESS; + this_i2c->options = options; + + /* Clear interrupts if required (depends on repeated starts).*/ + serial_interrupt = this_i2c->hw_reg_bit->CTRL_SI; + this_i2c->hw_reg_bit->CTRL_STA = 0x01; + + if ( serial_interrupt != 0 ) + { + this_i2c->hw_reg_bit->CTRL_SI = 0x00; + NVIC_ClearPendingIRQ( this_i2c->irqn ); + } + + stat_ctrl = this_i2c->hw_reg->STATUS; + + NVIC_EnableIRQ( this_i2c->irqn ); + + restore_interrupts( primask ); +} + +/*------------------------------------------------------------------------------ + * MSS_I2C_set_slave_rx_buffer() + * See "mss_i2c.h" for details of how to use this function. + */ +void MSS_I2C_set_slave_rx_buffer +( + mss_i2c_instance_t * this_i2c, + uint8_t * rx_buffer, + uint16_t rx_size +) +{ + uint32_t primask; + + ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) ); + + primask = disable_interrupts(); + + this_i2c->rx_buffer = rx_buffer; + this_i2c->rx_size = rx_size; + this_i2c->rx_idx = 0; + + restore_interrupts( primask ); +} + + +/*------------------------------------------------------------------------------ + * MSS_I2C_get_status() + * See "mss_i2c.h" for details of how to use this function. + */ +mss_i2c_status_t MSS_I2C_get_status +( + mss_i2c_instance_t * this_i2c +) +{ + ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) ); + + return this_i2c->status; +} + +/*------------------------------------------------------------------------------ + * MSS_I2C_set_slave_tx_buffer() + * See "mss_i2c.h" for details of how to use this function. + */ +void MSS_I2C_set_slave_tx_buffer +( + mss_i2c_instance_t * this_i2c, + uint8_t * tx_buffer, + uint16_t tx_size +) +{ + uint32_t primask; + + ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) ); + + primask = disable_interrupts(); + + this_i2c->tx_buffer = tx_buffer; + this_i2c->tx_size = tx_size; + this_i2c->tx_idx = 0; + + restore_interrupts( primask ); + + /* Set the assert acknowledge bit. */ + this_i2c->hw_reg_bit->CTRL_AA = 0x01; +} + +/*------------------------------------------------------------------------------ + * MSS_I2C_enable_slave_rx() + * See "mss_i2c.h" for details of how to use this function. + */ +void MSS_I2C_enable_slave_rx +( + mss_i2c_instance_t * this_i2c +) +{ + ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) ); + + /* Set the assert acknowledge bit. */ + this_i2c->hw_reg_bit->CTRL_AA = 0x01; + /* accept GC addressing. */ + this_i2c->hw_reg_bit->ADDR_GC = 0x01; + + NVIC_EnableIRQ( this_i2c->irqn ); +} + +/*------------------------------------------------------------------------------ + * MSS_I2C_wait_complete() + * See "mss_i2c.h" for details of how to use this function. + */ +mss_i2c_status_t MSS_I2C_wait_complete +( + mss_i2c_instance_t * this_i2c +) +{ + ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) ); + + while ( this_i2c->status == MSS_I2C_IN_PROGRESS ) + { + /* Wait for transaction to compltete.*/ + ; + } + return this_i2c->status; +} + +/*------------------------------------------------------------------------------ + * MSS I2C interrupt service routine. + *------------------------------------------------------------------------------ + * Parameters: + * + * mss_i2c_instance_t * this_i2c: + * Pointer to the mss_i2c_instance_t data structure holding all data related to + * the MSS I2C instance that generated the interrupt. + */ +static void mss_i2c_isr +( + mss_i2c_instance_t * this_i2c +) +{ + volatile uint8_t status; + uint8_t data; + uint8_t hold_bus; + uint8_t clear_irq = 1; + + ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) ); + + status = this_i2c->hw_reg->STATUS; + + switch( status ) + { + /************** MASTER TRANSMITTER / RECEIVER *******************/ + + case ST_START: /* start has been xmt'd */ + case ST_RESTART: /* repeated start has been xmt'd */ + this_i2c->hw_reg_bit->CTRL_STA = 0x0; + this_i2c->hw_reg->DATA = this_i2c->target_addr; + this_i2c->hw_reg_bit->DATA_DIR = this_i2c->dir; + + this_i2c->tx_idx = 0; + this_i2c->rx_idx = 0; + break; + + case ST_LOST_ARB: + /* Set start bit. Let's keep trying! Don't give up! */ + this_i2c->hw_reg_bit->CTRL_STA = 0x01; + break; + + /******************* MASTER TRANSMITTER *************************/ + case ST_SLAW_ACK: + /* call address has been xmt'd with ACK, time to send data byte and increment index. */ + if ( this_i2c->tx_idx < this_i2c->tx_size ) + { + /* load data byte */ + this_i2c->hw_reg->DATA = this_i2c->tx_buffer[this_i2c->tx_idx++]; + } + else + { + NVIC_DisableIRQ( this_i2c->irqn ); + } + break; + + case ST_SLAW_NACK: +#if 0 + /* SLA+W has been transmitted; not ACK has been received - let's stop. */ + this_i2c->hw_reg_bit->CTRL_STO = 0x01; + this_i2c->status = MSS_I2C_FAILED; +#endif + /* call address has been xmt'd with ACK, time to send data byte and increment index. */ + if ( this_i2c->tx_idx < this_i2c->tx_size ) + { + /* load data byte */ + this_i2c->hw_reg->DATA = this_i2c->tx_buffer[this_i2c->tx_idx++]; + } + else + { + NVIC_DisableIRQ( this_i2c->irqn ); + } + break; + + case ST_TX_DATA_ACK: + /* data byte has been xmt'd with ACK, time to send stop bit or repeated start. */ + if (this_i2c->tx_idx < this_i2c->tx_size) + { + this_i2c->hw_reg->DATA = this_i2c->tx_buffer[this_i2c->tx_idx++]; + } + else if ( this_i2c->transaction == MASTER_RANDOM_READ_TRANSACTION ) + { + /* We are finished sending the address offset part of a random read transaction. + * It is is time to send a restart in order to change direction. */ + this_i2c->dir = READ_DIR; + this_i2c->hw_reg_bit->CTRL_STA = 0x01; + } + else /* done sending. let's stop */ + { + hold_bus = this_i2c->options & MSS_I2C_HOLD_BUS; + if ( hold_bus == 0 ) + { + this_i2c->hw_reg_bit->CTRL_STO = 0x01; /*xmt stop condition */ + } + else + { + NVIC_DisableIRQ( this_i2c->irqn ); + clear_irq = 0; + } + this_i2c->status = MSS_I2C_SUCCESS; + } + break; + + case ST_TX_DATA_NACK: +#if 0 + /* data byte SENT, ACK to be received + * In fact, this means we've received a NACK (This may not be + * obvious, but if we've rec'd an ACK then we would be in state + * 0x28!) hence, let's send a stop bit + */ + this_i2c->hw_reg_bit->CTRL_STO = 0x01; + this_i2c->status = MSS_I2C_FAILED; +#endif + /* data byte has been xmt'd with ACK, time to send stop bit or repeated start. */ + if (this_i2c->tx_idx < this_i2c->tx_size) + { + this_i2c->hw_reg->DATA = this_i2c->tx_buffer[this_i2c->tx_idx++]; + } + else if ( this_i2c->transaction == MASTER_RANDOM_READ_TRANSACTION ) + { + /* We are finished sending the address offset part of a random read transaction. + * It is is time to send a restart in order to change direction. */ + this_i2c->dir = READ_DIR; + this_i2c->hw_reg_bit->CTRL_STA = 0x01; + } + else /* done sending. let's stop */ + { + hold_bus = this_i2c->options & MSS_I2C_HOLD_BUS; + if ( hold_bus == 0 ) + { + this_i2c->hw_reg_bit->CTRL_STO = 0x01; /*xmt stop condition */ + } + else + { + NVIC_DisableIRQ( this_i2c->irqn ); + clear_irq = 0; + } + this_i2c->status = MSS_I2C_SUCCESS; + } + break; + + /********************* MASTER (or slave?) RECEIVER *************************/ + + /* STATUS codes 08H, 10H, 38H are all covered in MTX mode */ + case ST_SLAR_ACK: /* SLA+R tx'ed. */ + /* Let's make sure we ACK the first data byte received (set AA bit in CTRL) unless + * the next byte is the last byte of the read transaction. + */ + if( this_i2c->rx_size > 1 ) + { + this_i2c->hw_reg_bit->CTRL_AA = 0x01; + } + else + { + this_i2c->hw_reg_bit->CTRL_AA = 0x00; + } + break; + + case ST_SLAR_NACK: /* SLA+R tx'ed; let's release the bus (send a stop condition) */ + this_i2c->hw_reg_bit->CTRL_STO = 0x01; + this_i2c->status = MSS_I2C_FAILED; + break; + + case ST_RX_DATA_ACK: /* Data byte received, ACK returned */ + /* First, get the data */ + this_i2c->rx_buffer[this_i2c->rx_idx++] = this_i2c->hw_reg->DATA; + + if( this_i2c->rx_idx >= this_i2c->rx_size - 1) + { + /* If we're at the second last byte, let's set AA to 0 so + * we return a NACK at the last byte. */ + this_i2c->hw_reg_bit->CTRL_AA = 0x00; + } + break; + + case ST_RX_DATA_NACK: /* Data byte received, NACK returned */ + /* Get the data, then send a stop condition */ + this_i2c->rx_buffer[this_i2c->rx_idx++] = this_i2c->hw_reg->DATA; + + hold_bus = this_i2c->options & MSS_I2C_HOLD_BUS; + if ( hold_bus == 0 ) + { + this_i2c->hw_reg_bit->CTRL_STO = 0x01; /*xmt stop condition */ + } + else + { + NVIC_DisableIRQ( this_i2c->irqn ); + clear_irq = 0; + } + + this_i2c->status = MSS_I2C_SUCCESS; + break; + + /******************** SLAVE RECEIVER **************************/ + case ST_GCA_NACK: /* NACK after, GCA addressing */ + case ST_SLA_NACK: /* Get Data, but also re-enable AA (assert ack) bit for future transmissions */ + if ( this_i2c->rx_buffer != 0 ) + { + this_i2c->rx_buffer[this_i2c->rx_idx] = this_i2c->hw_reg->DATA; + } + this_i2c->hw_reg_bit->CTRL_AA = 0x01; + break; + + case ST_SLAVE_SLAW: /* SLA+W received, ACK returned */ + this_i2c->transaction = WRITE_SLAVE_TRANSACTION; + this_i2c->rx_idx = 0; + this_i2c->random_read_addr = 0; +#ifndef INCLUDE_SLA_IN_RX_PAYLOAD + /* Only break from this case if the slave address must NOT be included at the + * beginning of the received write data. */ + break; +#endif + case ST_GCA_ACK: /* DATA received; ACK sent after GCA */ + case ST_RDATA: /* DATA received; must clear DATA register */ + if (this_i2c->rx_idx >= this_i2c->rx_size - 2) + { + this_i2c->hw_reg_bit->CTRL_AA = 0x00; /* send a NACK when done (next reception) */ + } + data = this_i2c->hw_reg->DATA; + this_i2c->rx_buffer[this_i2c->rx_idx++] = data; + this_i2c->random_read_addr = (this_i2c->random_read_addr << 8) + data; + + break; + + case ST_RSTOP: + /* STOP or repeated START occured. */ + /* We cannot be sure if the transaction has actually completed as + * this hardware state reports that either a STOP or repeated START + * condition has occured. We assume that this is a repeated START + * if the transaction was a write from the master to this point.*/ + if ( this_i2c->transaction == WRITE_SLAVE_TRANSACTION ) + { + if ( this_i2c->rx_idx == this_i2c->slave_mem_offset_length ) + { + this_i2c->transaction = RANDOM_READ_SLAVE_TRANSACTION; + this_i2c->tx_idx = this_i2c->random_read_addr; + } + else + { + /* Call the slave's write transaction handler if it exists. */ + if ( this_i2c->slave_write_handler != 0 ) + { + mss_i2c_slave_handler_ret_t h_ret; + h_ret = this_i2c->slave_write_handler( this_i2c->rx_buffer, (uint16_t)this_i2c->rx_idx ); + if ( MSS_I2C_REENABLE_SLAVE_RX == h_ret ) + { + this_i2c->hw_reg_bit->CTRL_AA = 0x01; + } + else + { + this_i2c->hw_reg_bit->CTRL_AA = 0x00; + } + } + } + } + /* Mark any previous master write transaction as complete. */ + this_i2c->status = MSS_I2C_SUCCESS; + break; + + case ST_SLV_RST: /* SMBUS ONLY: timeout state. must clear interrupt */ + case ST_SLV_LA: /* Arbitr. lost (SLA rec'd) */ + case ST_GCA: /* General call address received, ACK returned */ + case ST_GCA_LA: /* Arbitr. lost (GCA rec'd) */ + /* do nothing */ + break; + + /****************** SLAVE TRANSMITTER **************************/ + case ST_SLAVE_SLAR_ACK: /* SLA+R received, ACK returned */ + case ST_SLARW_LA: /* Arbitration lost, and: */ + case ST_RACK: /* Data tx'ed, ACK received */ + if ( status == ST_SLAVE_SLAR_ACK ) + { + this_i2c->transaction = READ_SLAVE_TRANSACTION; + this_i2c->random_read_addr = 0; + } + /* Load the data, and determine if it is the last one */ + this_i2c->hw_reg->DATA = this_i2c->tx_buffer[this_i2c->tx_idx++]; + if (this_i2c->tx_idx >= this_i2c->tx_size - 1) /* last byte? */ + { + this_i2c->hw_reg_bit->CTRL_AA = 0x00; + /* Next read transaction will result in slave's transmit buffer + * being sent from the first byte. */ + this_i2c->tx_idx = 0; + } + break; + + case ST_SLAVE_RNACK: /* Data byte has been transmitted; not-ACK has been received. */ + /* We assume that the transaction will be stopped by the master. + * Reset tx_idx so that a subsequent read will result in the slave's + * transmit buffer being sent from the first byte. */ + this_i2c->tx_idx = 0; + break; + + case ST_FINAL: /* Last Data byte tx'ed, ACK recieved */ + default: + /* do nothing */ + break; + } + + if ( clear_irq ) + { + /* clear interrupt. */ + this_i2c->hw_reg_bit->CTRL_SI = 0x00; + } + + /* Read the status register to ensure the last I2C registers write took place + * in a system built around a bus making use of posted writes. */ + status = this_i2c->hw_reg->STATUS; +} + +/*------------------------------------------------------------------------------ + * + */ +uint32_t disable_interrupts( void ) +{ + uint32_t primask; + primask = __get_PRIMASK(); + return primask; +} + +/*------------------------------------------------------------------------------ + * + */ +void restore_interrupts( uint32_t primask ) +{ + __set_PRIMASK( primask ); +} + +/*------------------------------------------------------------------------------ + * + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void I2C0_IRQHandler( void ) +#else +void I2C0_IRQHandler( void ) +#endif +{ + mss_i2c_isr( &g_mss_i2c0 ); + NVIC_ClearPendingIRQ( I2C0_IRQn ); +} + +/*------------------------------------------------------------------------------ + * + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void I2C1_IRQHandler( void ) +#else +void I2C1_IRQHandler( void ) +#endif +{ + mss_i2c_isr( &g_mss_i2c1 ); + NVIC_ClearPendingIRQ( I2C1_IRQn ); +} + +#ifdef __cplusplus +} +#endif diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/I2C/i2c.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/I2C/i2c.h new file mode 100644 index 000000000..63220c37c --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/I2C/i2c.h @@ -0,0 +1,775 @@ +/******************************************************************************* + * (c) Copyright 2007-2008 Actel Corporation. All rights reserved. + * + * SmartFusion microcontroller subsystem I2C bare metal software driver public + * API. + * + * SVN $Revision: 2150 $ + * SVN $Date: 2010-02-11 14:39:24 +0000 (Thu, 11 Feb 2010) $ + */ +/*=========================================================================*//** + @mainpage SmartFusion MSS I2C Bare Metal Driver. + + @section intro_sec Introduction + The SmartFusion™ microcontroller subsystem (MSS) includes two I2C peripherals + for serial communication. This driver provides a set of functions for + controlling the MSS I2Cs as part of a bare metal system where no operating + system is available. These drivers can be adapted for use as part of an + operating system, but the implementation of the adaptation layer between this + driver and the operating system's driver model is outside the scope of this + driver. + + @section hw_dependencies Hardware Flow Dependencies + The configuration of all features of the MSS I2Cs is covered by this driver + with the exception of the SmartFusion IOMUX configuration. SmartFusion allows + multiple non-concurrent uses of some external pins through IOMUX configuration. + This feature allows optimization of external pin usage by assigning external + pins for use by either the microcontroller subsystem or the FPGA fabric. The + MSS I2Cs serial signals are routed through IOMUXes to the SmartFusion device + external pins. These IOMUXes are automatically configured correctly by the MSS + configurator tool in the hardware flow when the MSS I2Cs are enabled in that + tool. You must ensure that the MSS I2Cs are enabled by the MSS configurator + tool in the hardware flow; otherwise the serial inputs and outputs will not be + connected to the chip's external pins. For more information on IOMUX, refer to + the IOMUX section of the SmartFusion Datasheet. + The base address, register addresses and interrupt number assignment for the + MSS I2C blocks are defined as constants in the SmartFusion CMSIS-PAL. You must + ensure that the SmartFusion CMSIS-PAL is either included in the software tool + chain used to build your project or is included in your project. + + @section theory_op Theory of Operation + The MSS I2C driver functions are grouped into the following categories: + • Initialization and configuration functions + • Interrupt control + • I2C master operations – functions to handle write, read and write-read transactions + • I2C slave operations – functions to handle write, read and write-read transactions + + Initialization and Configuration + The MSS I2C driver is initialized through a call to the MSS_I2C_init() + function. This function takes the MSS I2C's configuration as parameters. The + MSS_I2C_init() function must be called before any other MSS I2C driver + functions can be called. The first parameter of the MSS_I2C_init() function + is a pointer to one of two global data structures used by the driver to + store state information for each MSS I2C. A pointer to these data structures + is also used as first parameter to any of the driver functions to identify + which MSS I2C will be used by the called function. The names of these two + data structures are g_mss_i2c0 and g_mss_i2c1. Therefore any call to an MSS + I2C driver function should be of the form MSS_I2C_function_name( &g_mss_i2c0, ... ) + or MSS_I2C_function_name( &g_mss_i2c1, ... ). + The MSS_I2C_init() function call for each MSS I2C also takes the I2C serial + address assigned to the MSS I2C and the serial clock divider to be used to + generate its I2C clock as configuration parameters. + + Interrupt Control + The MSS I2C driver is interrupt driven and it enables and disables the + generation of interrupts by MSS I2C at various times when it is operating. + The driver automatically handles MSS I2C interrupts internally, including + enabling disabling and clearing MSS I2C interrupts in the Cortex-M3 + interrupt controller when required. + The function MSS_I2C_register_write_handler() is used to register a write + handler function with the MSS I2C driver that it will call on completion of + an I2C write transaction by the MSS I2C slave. It is your responsibility to + create and register the implementation of this handler function that will + process or trigger the processing of the received data. + Transaction Types + The MSS I2C driver is designed to handle three types of I2C transaction: + • Write transactions + • Read transactions + • Write-read transactions + + Write transaction + The master I2C device initiates a write transaction by sending a START bit + as soon as the bus becomes free. The START bit is followed by the 7-bit + serial address of the target slave device followed by the read/write bit + indicating the direction of the transaction. The slave acknowledges receipt + of it’s address with an acknowledge bit. The master sends data one byte at + a time to the slave, which must acknowledge receipt of each byte for the + next byte to be sent. The master sends a STOP bit to complete the transaction. + The slave can abort the transaction by replying with a non-acknowledge bit + instead of an acknowledge. + The application programmer can choose not to send a STOP bit at the end of + the transaction causing the next transaction to begin with a repeated START bit. + + Read transaction + The master I2C device initiates a read transaction by sending a START bit + as soon as the bus becomes free. The START bit is followed by the 7-bit + serial address of the target slave device followed by the read/write bit + indicating the direction of the transaction. The slave acknowledges receipt + of it’s slave address with an acknowledge bit. The slave sends data one byte + at a time to the master, which must acknowledge receipt of each byte for the + next byte to be sent. The master sends a non-acknowledge bit following the + last byte it wishes to read followed by a STOP bit. + The application programmer can choose not to send a STOP bit at the end of + the transaction causing the next transaction to begin with a repeated START bit. + + Write-read transaction + The write-read transaction is a combination of a write transaction + immediately followed by a read transaction. There is no STOP bit between + the write and read phases of a write-read transaction. A repeated START + bit is sent between the write and read phases. + The write-read transaction is typically used to send a command or offset + in the write transaction specifying the logical data to be transferred + during the read phase. + The application programmer can choose not to send a STOP bit at the end of + the transaction causing the next transaction to begin with a repeated START bit. + + Master Operations + The application can use the MSS_I2C_write(), MSS_I2C_read() and MSS_I2C_write_read() + functions to initiate an I2C bus transaction. The application can then wait + for the transaction to complete using the MSS_I2C_wait_complete() function + or poll the status of the I2C transaction using the MSS_I2C_get_status() + function until it returns a value different from MSS_I2C_IN_PROGRESS. + + Slave Operations + The configuration of the MSS I2C driver to operate as an I2C slave requires + the use of the following functions: + • MSS_I2C_set_slave_tx_buffer() + • MSS_I2C_set_slave_rx_buffer() + • MSS_I2C_set_slave_mem_offset_length() + • MSS_I2C_register_write_handler() + • MSS_I2C_enable_slave_rx() + Use of all functions is not required if the slave I2C does not need to support + all types of I2C read transactions. The subsequent sections list the functions + that must be used to support each transaction type. + + Responding to read transactions + The following functions are used to configure the MSS I2C driver to respond + to I2C read transactions: + • MSS_I2C_set_slave_tx_buffer() + • MSS_I2C_enable_slave_rx() + The function MSS_I2C_set_slave_tx_buffer() specifies the data buffer that + will be transmitted when the I2C slave is the target of an I2C read + transaction. It is then up to the application to manage the content of that + buffer to control the data that will be transmitted to the I2C master as a + result of the read transaction. + The function MSS_I2C_enable_slave_rx() enables the MSS I2C hardware instance + to respond to I2C transactions. It must be called after the MSS I2C driver + has been configured to respond to the required transaction types. + + Responding to write transactions + The following functions are used to configure the MSS I2C driver to respond + to I2C write transactions: + • MSS_I2C_set_slave_rx_buffer() + • MSS_I2C_register_write_handler() + • MSS_I2C_enable_slave_rx() + The function MSS_I2C_set_slave_rx_buffer() specifies the data buffer that + will be used to store the data received by the I2C slave when it is the + target an I2C write transaction. + The function MSS_I2C_register_write_handler() specifies the handler function + that must be called on completion of the I2C write transaction. It is this + handler function that will process or trigger the processing of the received + data. + The function MSS_I2C_enable_slave_rx() enables the MSS I2C hardware instance + to respond to I2C transactions. It must be called after the MSS I2C driver + has been configured to respond to the required transaction types. + + Responding to write-read transactions + The following functions are used to configure the MSS I2C driver to respond + to write-read transactions: + • MSS_I2C_set_slave_tx_buffer() + • MSS_I2C_set_slave_rx_buffer() + • MSS_I2C_set_slave_mem_offset_length() + • MSS_I2C_enable_slave_rx() + The function MSS_I2C_set_slave_mem_offset_length() specifies the number of + bytes expected by the I2C slave during the write phase of the write-read + transaction. + The function MSS_I2C_set_slave_tx_buffer() specifies the data that will be + transmitted to the I2C master during the read phase of the write-read + transaction. The value received by the I2C slave during the write phase of + the transaction will be used as an index into the transmit buffer specified + by this function to decide which part of the transmit buffer will be + transmitted to the I2C master as part of the read phase of the write-read + transaction. + The function MSS_I2C_set_slave_rx_buffer() specifies the data buffer that + will be used to store the data received by the I2C slave during the write + phase of the write-read transaction. This buffer must be at least large + enough to accommodate the number of bytes specified through the + MSS_I2C_set_slave_mem_offset_length() function. + The function MSS_I2C_enable_slave_rx() enables the MSS I2C hardware + instance to respond to I2C transactions. It must be called after the MSS + I2C driver has been configured to respond to the required transaction types. + *//*=========================================================================*/ +#ifndef I2C_H_ +#define I2C_H_ + +#include "../../CMSIS/a2fxxxm3.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*-------------------------------------------------------------------------*//** + The mss_i2c_clock_divider_t type is used to specify the divider to be applied + to the MSS I2C BCLK signal in order to generate the I2C clock. + */ +typedef enum mss_i2c_clock_divider { + MSS_I2C_PCLK_DIV_256 = 0, + MSS_I2C_PCLK_DIV_224, + MSS_I2C_PCLK_DIV_192, + MSS_I2C_PCLK_DIV_160, + MSS_I2C_PCLK_DIV_960, + MSS_I2C_PCLK_DIV_120, + MSS_I2C_PCLK_DIV_60, + MSS_I2C_BCLK_DIV_8 +} mss_i2c_clock_divider_t; + +/*-------------------------------------------------------------------------*//** + The MSS_I2C_RELEASE_BUS constant is used to specify the options parameter to + functions MSS_I2C_read(), MSS_I2C_write() and MSS_I2C_write_read() to indicate + that a STOP bit must be generated at the end of the I2C transaction to release + the bus. + */ +#define MSS_I2C_RELEASE_BUS 0x00 + +/*-------------------------------------------------------------------------*//** + The MSS_I2C_HOLD_BUS constant is used to specify the options parameter to + functions MSS_I2C_read(), MSS_I2C_write() and MSS_I2C_write_read() to indicate + that a STOP bit must not be generated at the end of the I2C transaction in + order to retain the bus ownership. This will cause the next transaction to + begin with a repeated START bit and no STOP bit between the transactions. + */ +#define MSS_I2C_HOLD_BUS 0x01 + +/*-------------------------------------------------------------------------*//** + The mss_i2c_status_t type is used to report the status of I2C transactions. + */ +typedef enum mss_i2c_status +{ + MSS_I2C_SUCCESS = 0, + MSS_I2C_IN_PROGRESS, + MSS_I2C_FAILED +} mss_i2c_status_t; + +/*-------------------------------------------------------------------------*//** + The mss_i2c_slave_handler_ret_t type is used by slave write handler functions + to indicate whether the received data buffer should be released or not. + */ +typedef enum mss_i2c_slave_handler_ret { + MSS_I2C_REENABLE_SLAVE_RX = 0, + MSS_I2C_PAUSE_SLAVE_RX = 1 +} mss_i2c_slave_handler_ret_t; + +/*-------------------------------------------------------------------------*//** + Slave write handler functions prototype. + ------------------------------------------------------------------------------ + This defines the function prototype that must be followed by MSS I2C slave + write handler functions. These functions are registered with the MSS I2C driver + through the MSS_I2C_register_write_handler() function. + + Declaring and Implementing Slave Write Handler Functions: + Slave write handler functions should follow the following prototype: + mss_i2c_slave_handler_ret_t write_handler( uint8_t * data, uint16_t size ); + + The data parameter is a pointer to a buffer (received data buffer) holding + the data written to the MSS I2C slave. + The size parameter is the number of bytes held in the received data buffer. + Handler functions must return one of the following values: + • MSS_I2C_REENABLE_SLAVE_RX + • MSS_I2C_PAUSE_SLAVE_RX. + If the handler function returns MSS_I2C_REENABLE_SLAVE_RX, the driver will + release the received data buffer and allow further I2C write transactions to + the MSS I2C slave to take place. + If the handler function returns MSS_I2C_PAUSE_SLAVE_RX, the MSS I2C slave + will respond to subsequent write requests with a non-acknowledge bit (NACK), + until the received data buffer content has been processed by some other part + of the software application. + A call to MSS_I2C_enable_slave_rx() is required at some point after + returning MSS_I2C_PAUSE_SLAVE_RX in order to release the received data + buffer so it can be used to store data received by subsequent I2C write + transactions. + */ +typedef mss_i2c_slave_handler_ret_t (*mss_i2c_slave_wr_handler_t)( uint8_t *, uint16_t ); + +/*-------------------------------------------------------------------------*//** + mss_i2c_instance_t + ------------------------------------------------------------------------------ + There is one instance of this structure for each of the microcontroller + subsystem's I2Cs. Instances of this structure are used to identify a specific + I2C. A pointer to an instance of the mss_i2c_instance_t structure is passed as + the first parameter to MSS I2C driver functions to identify which I2C should + perform the requested operation. + */ +typedef struct mss_i2c_instance +{ + uint_fast8_t ser_address; + /* Transmit related info:*/ + uint_fast8_t target_addr; + + /* Current transaction type (WRITE, READ, RANDOM_READ)*/ + uint8_t transaction; + + uint_fast16_t random_read_addr; + + uint8_t options; + + /* I2C hardware instance identification */ + IRQn_Type irqn; + I2C_TypeDef * hw_reg; + I2C_BitBand_TypeDef * hw_reg_bit; + + /* TX INFO: */ + const uint8_t * tx_buffer; + uint_fast16_t tx_size; + uint_fast16_t tx_idx; + uint_fast8_t dir; + + /* RX INFO: */ + uint8_t * rx_buffer; + uint_fast16_t rx_size; + uint_fast16_t rx_idx; + + /* status variable: */ + volatile mss_i2c_status_t status; + + /* Slave data: */ + uint_fast8_t slave_mem_offset_length; + mss_i2c_slave_wr_handler_t slave_write_handler; + +} mss_i2c_instance_t; + +/*-------------------------------------------------------------------------*//** + This instance of mss_i2c_instance_t holds all data related to the operations + performed by MSS I2C 0. A pointer to g_mss_i2c0 is passed as the first + parameter to MSS I2C driver functions to indicate that MSS I2C 0 should + perform the requested operation. + */ +extern mss_i2c_instance_t g_mss_i2c0; + +/*-------------------------------------------------------------------------*//** + This instance of mss_i2c_instance_t holds all data related to the operations + performed by MSS I2C 1. A pointer to g_mss_i2c1 is passed as the first + parameter to MSS I2C driver functions to indicate that MSS I2C 1 should + perform the requested operation. + */ +extern mss_i2c_instance_t g_mss_i2c1; + +/*-------------------------------------------------------------------------*//** + MSS I2C initialisation routine. + ------------------------------------------------------------------------------ + The MSS_I2C_init() function initializes and configures hardware and data + structures of one of the SmartFusion MSS I2Cs. + ------------------------------------------------------------------------------ + @param this_i2c: + The this_i2c parameter is a pointer to an mss_i2c_instance_t structure + identifying the MSS I2C hardware block to be initialized. There are two such + data structures, g_mss_i2c0 and g_mss_i2c1, associated with MSS I2C 0 and + MSS I2C 1 respectively. This parameter must point to either the g_mss_i2c0 + or g_mss_i2c1 global data structure defined within the I2C driver. + + @param ser_address: + This parameter sets the I2C serial address being initialized. It is the I2C + bus address to which the MSS I2C instance will respond. Any 8 bit address is + allowed. + + @param ser_clock_speed: + This parameter sets the I2C serial clock frequency. It selects the divider + that will be used to generate the serial clock from the APB clock. It can be + one of the following: + • MSS_I2C_PCLK_DIV_256 + • MSS_I2C_PCLK_DIV_224 + • MSS_I2C_PCLK_DIV_192 + • MSS_I2C_PCLK_DIV_160 + • MSS_I2C_PCLK_DIV_960 + • MSS_I2C_PCLK_DIV_120 + • MSS_I2C_PCLK_DIV_60 + • MSS_I2C_BCLK_DIV_8 + */ +void MSS_I2C_init +( + mss_i2c_instance_t * this_i2c, + uint8_t ser_address, + mss_i2c_clock_divider_t ser_clock_speed +); + +/******************************************************************************* + ******************************************************************************* + * + * Master specific functions + * + * The following functions are only used within an I2C master's implementation. + */ + +/*-------------------------------------------------------------------------*//** + I2C master write function. + ------------------------------------------------------------------------------ + This function initiates an I2C master write transaction. This function returns + immediately after initiating the transaction. The content of the write buffer + passed as parameter should not be modified until the write transaction + completes. It also means that the memory allocated for the write buffer should + not be freed or go out of scope before the write completes. You can check for + the write transaction completion using the MSS_I2C_status() function. + ------------------------------------------------------------------------------ + @param this_i2c: + The this_i2c parameter is a pointer to an mss_i2c_instance_t structure + identifying the MSS I2C hardware block that will perform the requested + function. There are two such data structures, g_mss_i2c0 and g_mss_i2c1, + associated with MSS I2C 0 and MSS I2C 1 respectively. This parameter must + point to either the g_mss_i2c0 or g_mss_i2c1 global data structure defined + within the I2C driver. + + @param serial_addr: + This parameter specifies the serial address of the target I2C device. + + @param write_buffer: + This parameter is a pointer to a buffer holding the data to be written to + the target I2C device. + Care must be taken not to release the memory used by this buffer before the + write transaction completes. For example, it is not appropriate to return + from a function allocating this buffer as an array variable before the write + transaction completes as this would result in the buffer's memory being + de-allocated from the stack when the function returns. This memory could + then be subsequently reused and modified causing unexpected data to be + written to the target I2C device. + + @param write_size: + Number of bytes held in the write_buffer to be written to the target I2C + device. + + @param options: + The options parameter is used to indicate if the I2C bus should be released + on completion of the write transaction. Using the MSS_I2C_RELEASE_BUS + constant for the options parameter causes a STOP bit to be generated at the + end of the write transaction causing the bus to be released for other I2C + devices to use. Using the MSS_I2C_HOLD_BUS constant as options parameter + prevents a STOP bit from being generated at the end of the write + transaction, preventing other I2C devices from initiating a bus transaction. + */ +void MSS_I2C_write +( + mss_i2c_instance_t * this_i2c, + uint8_t serial_addr, + const uint8_t * write_buffer, + uint16_t write_size, + uint8_t options +); + +/*-------------------------------------------------------------------------*//** + I2C master read. + ------------------------------------------------------------------------------ + This function initiates an I2C master read transaction. This function returns + immediately after initiating the transaction. + The content of the read buffer passed as parameter should not be modified + until the read transaction completes. It also means that the memory allocated + for the read buffer should not be freed or go out of scope before the read + completes. You can check for the read transaction completion using the + MSS_I2C_status() function. + ------------------------------------------------------------------------------ + @param this_i2c: + The this_i2c parameter is a pointer to an mss_i2c_instance_t structure + identifying the MSS I2C hardware block that will perform the requested + function. There are two such data structures, g_mss_i2c0 and g_mss_i2c1, + associated with MSS I2C 0 and MSS I2C 1 respectively. This parameter must + point to either the g_mss_i2c0 or g_mss_i2c1 global data structure defined + within the I2C driver. + + @param serial_addr: + This parameter specifies the serial address of the target I2C device. + + @param read_buffer + Pointer to a buffer where the data received from the target device will be + stored. + Care must be taken not to release the memory used by this buffer before the + read transaction completes. For example, it is not appropriate to return + from a function allocating this buffer as an array variable before the read + transaction completes as this would result in the buffer's memory being + de-allocated from the stack when the function returns. This memory could + then be subsequently reallocated resulting in the read transaction + corrupting the newly allocated memory. + + @param read_size: + This parameter is the number of bytes to read from the target device. This + size must not exceed the size of the read_buffer buffer. + + @param options: + The options parameter is used to indicate if the I2C bus should be released + on completion of the read transaction. Using the MSS_I2C_RELEASE_BUS + constant for the options parameter causes a STOP bit to be generated at the + end of the read transaction causing the bus to be released for other I2C + devices to use. Using the MSS_I2C_HOLD_BUS constant as options parameter + prevents a STOP bit from being generated at the end of the read transaction, + preventing other I2C devices from initiating a bus transaction. + */ +void MSS_I2C_read +( + mss_i2c_instance_t * this_i2c, + uint8_t serial_addr, + uint8_t * read_buffer, + uint16_t read_size, + uint8_t options +); + +/*-------------------------------------------------------------------------*//** + I2C master write-read + ------------------------------------------------------------------------------ + This function initiates an I2C write-read transaction where data is first + written to the target device before issuing a restart condition and changing + the direction of the I2C transaction in order to read from the target device. + ------------------------------------------------------------------------------ + @param this_i2c: + The this_i2c parameter is a pointer to an mss_i2c_instance_t structure + identifying the MSS I2C hardware block that will perform the requested + function. There are two such data structures, g_mss_i2c0 and g_mss_i2c1, + associated with MSS I2C 0 and MSS I2C 1 respectively. This parameter must + point to either the g_mss_i2c0 or g_mss_i2c1 global data structure defined + within the I2C driver. + + @param serial_addr: + This parameter specifies the serial address of the target I2C device. + + @param addr_offset: + This parameter is a pointer to the buffer containing the data that will be + sent to the slave during the write phase of the write-read transaction. This + data is typically used to specify an address offset specifying to the I2C + slave device what data it must return during the read phase of the + write-read transaction. + + @param offset_size: + This parameter specifies the number of offset bytes to be written during the + write phase of the write-read transaction. This is typically the size of the + buffer pointed to by the addr_offset parameter. + + @param read_buffer: + This parameter is a pointer to the buffer where the data read from the I2C + slave will be stored. + + @param read_size: + This parameter specifies the number of bytes to read from the target I2C + slave device. This size must not exceed the size of the buffer pointed to by + the read_buffer parameter. + + @param options: + The options parameter is used to indicate if the I2C bus should be released + on completion of the write-read transaction. Using the MSS_I2C_RELEASE_BUS + constant for the options parameter causes a STOP bit to be generated at the + end of the write-read transaction causing the bus to be released for other + I2C devices to use. Using the MSS_I2C_HOLD_BUS constant as options parameter + prevents a STOP bit from being generated at the end of the write-read + transaction, preventing other I2C devices from initiating a bus transaction. + */ +void MSS_I2C_write_read +( + mss_i2c_instance_t * this_i2c, + uint8_t serial_addr, + const uint8_t * addr_offset, + uint16_t offset_size, + uint8_t * read_buffer, + uint16_t read_size, + uint8_t options +); + +/*-------------------------------------------------------------------------*//** + I2C status + ------------------------------------------------------------------------------ + This function indicates the current state of a MSS I2C instance. + ------------------------------------------------------------------------------ + @param this_i2c: + The this_i2c parameter is a pointer to an mss_i2c_instance_t structure + identifying the MSS I2C hardware block that will perform the requested + function. There are two such data structures, g_mss_i2c0 and g_mss_i2c1, + associated with MSS I2C 0 and MSS I2C 1 respectively. This parameter must + point to either the g_mss_i2c0 or g_mss_i2c1 global data structure defined + within the I2C driver. + ------------------------------------------------------------------------------ + @return + The return value indicates the current state of a MSS I2C instance or the + outcome of the previous transaction if no transaction is in progress. + Possible return values are: + SUCCESS + The last I2C transaction has completed successfully. + IN_PROGRESS + There is an I2C transaction in progress. + FAILED + The last I2C transaction failed. + + */ +mss_i2c_status_t MSS_I2C_get_status +( + mss_i2c_instance_t * this_i2c +); + +/*-------------------------------------------------------------------------*//** + Wait for I2C transaction completion. + ------------------------------------------------------------------------------ + This function waits for the current I2C transaction to complete. The return + value indicates whether the last I2C transaction was successful, or is still + in progress, or failed. + ------------------------------------------------------------------------------ + @param this_i2c: + The this_i2c parameter is a pointer to an mss_i2c_instance_t structure + identifying the MSS I2C hardware block that will perform the requested + function. There are two such data structures, g_mss_i2c0 and g_mss_i2c1, + associated with MSS I2C 0 and MSS I2C 1 respectively. This parameter must + point to either the g_mss_i2c0 or g_mss_i2c1 global data structure defined + within the I2C driver. + ------------------------------------------------------------------------------ + @return + The return value indicates the outcome of the last I2C transaction. It can + be one of the following: + MSS_I2C_SUCCESS + The last I2C transaction has completed successfully. + MSS_I2C_IN_PROGRESS + The current I2C transaction is still in progress. + MSS_I2C_FAILED + The last I2C transaction failed. + */ +mss_i2c_status_t MSS_I2C_wait_complete +( + mss_i2c_instance_t * this_i2c +); + + +/******************************************************************************* + ******************************************************************************* + * + * Slave specific functions + * + * The following functions are only used within the implementation of an I2C + * slave device. + */ + +/*-------------------------------------------------------------------------*//** + I2C slave transmit buffer configuration. + ------------------------------------------------------------------------------ + This function specifies the memory buffer holding the data that will be sent + to the I2C master when this MSS I2C instance is the target of an I2C read or + write-read transaction. + ------------------------------------------------------------------------------ + @param this_i2c: + The this_i2c parameter is a pointer to an mss_i2c_instance_t structure + identifying the MSS I2C hardware block that will perform the requested + function. There are two such data structures, g_mss_i2c0 and g_mss_i2c1, + associated with MSS I2C 0 and MSS I2C 1 respectively. This parameter must + point to either the g_mss_i2c0 or g_mss_i2c1 global data structure defined + within the I2C driver. + + @param tx_buffer: + This parameter is a pointer to the memory buffer holding the data to be + returned to the I2C master when this MSS I2C instance is the target of an + I2C read or write-read transaction. + + @param tx_size: + Size of the transmit buffer pointed to by the tx_buffer parameter. + */ +void MSS_I2C_set_slave_tx_buffer +( + mss_i2c_instance_t * this_i2c, + uint8_t * tx_buffer, + uint16_t tx_size +); + +/*-------------------------------------------------------------------------*//** + I2C slave receive buffer configuration. + ------------------------------------------------------------------------------ + This function specifies the memory buffer that will be used by the MSS I2C + instance to receive data when it is a slave. This buffer is the memory where + data will be stored when the MSS I2C is the target of an I2C master write + transaction (i.e. when it is the slave). + ------------------------------------------------------------------------------ + @param this_i2c: + The this_i2c parameter is a pointer to an mss_i2c_instance_t structure + identifying the MSS I2C hardware block that will perform the requested + function. There are two such data structures, g_mss_i2c0 and g_mss_i2c1, + associated with MSS I2C 0 and MSS I2C 1 respectively. This parameter must + point to either the g_mss_i2c0 or g_mss_i2c1 global data structure defined + within the I2C driver. + + @param rx_buffer: + This parameter is a pointer to the memory buffer allocated by the caller + software to be used as a slave receive buffer. + + @param rx_size: + Size of the slave receive buffer. This is the amount of memory that is + allocated to the buffer pointed to by rx_buffer. + Note: This buffer size will indirectly specify the maximum I2C write + transaction length this MSS I2C instance can be the target of. This + is because this MSS I2C instance will respond to further received + bytes with a non-acknowledge bit (NACK) as soon as its receive + buffer is full. This will cause the write transaction to fail. + */ +void MSS_I2C_set_slave_rx_buffer +( + mss_i2c_instance_t * this_i2c, + uint8_t * rx_buffer, + uint16_t rx_size +); + +/*-------------------------------------------------------------------------*//** + I2C slave memory offset length configuration. + ------------------------------------------------------------------------------ + This function is used as part of the configuration of a MSS I2C instance for + operation as a slave supporting write-read transactions. It specifies the + number of bytes expected as part of the write phase of a write-read + transaction. The bytes received during the write phase of a write-read + transaction will be interpreted as an offset into the slave’s transmit buffer. + This allows random access into the I2C slave transmit buffer from a remote + I2C master. + ------------------------------------------------------------------------------ + @param this_i2c: + The this_i2c parameter is a pointer to an mss_i2c_instance_t structure + identifying the MSS I2C hardware block that will perform the requested + function. There are two such data structures, g_mss_i2c0 and g_mss_i2c1, + associated with MSS I2C 0 and MSS I2C 1 respectively. This parameter must + point to either the g_mss_i2c0 or g_mss_i2c1 global data structure defined + within the I2C driver. + + @param offset_length: + The offset_length parameter configures the number of bytes to be interpreted + by the MSS I2C slave as a memory offset value during the write phase of + write-read transactions. + */ +void MSS_I2C_set_slave_mem_offset_length +( + mss_i2c_instance_t * this_i2c, + uint8_t offset_length +); + +/*-------------------------------------------------------------------------*//** + I2C write handler registration. + ------------------------------------------------------------------------------ + Register the function that will be called to process the data written to this + MSS I2C instance when it is the slave in an I2C write transaction. + Note: The write handler is not called as a result of a write-read transaction. + The write data of a write read transaction is interpreted as an offset + into the slave’s transmit buffer and handled by the driver. + ------------------------------------------------------------------------------ + @param this_i2c: + The this_i2c parameter is a pointer to an mss_i2c_instance_t structure + identifying the MSS I2C hardware block that will perform the requested + function. There are two such data structures, g_mss_i2c0 and g_mss_i2c1, + associated with MSS I2C 0 and MSS I2C 1 respectively. This parameter must + point to either the g_mss_i2c0 or g_mss_i2c1 global data structure defined + within the I2C driver. + + @param handler: + Pointer to the function that will process the I2C write request. + */ +void MSS_I2C_register_write_handler +( + mss_i2c_instance_t * this_i2c, + mss_i2c_slave_wr_handler_t handler +); + +/*-------------------------------------------------------------------------*//** + I2C slave receive enable. + ------------------------------------------------------------------------------ + Enables the MSS I2C instance identified through the this_i2c parameter to + receive data when it is the target of an I2C write or write-read transaction. + ------------------------------------------------------------------------------ + @param this_i2c: + The this_i2c parameter is a pointer to an mss_i2c_instance_t structure + identifying the MSS I2C hardware block that will perform the requested + function. There are two such data structures, g_mss_i2c0 and g_mss_i2c1, + associated with MSS I2C 0 and MSS I2C 1 respectively. This parameter must + point to either the g_mss_i2c0 or g_mss_i2c1 global data structure defined + within the I2C driver. + */ +void MSS_I2C_enable_slave_rx +( + mss_i2c_instance_t * this_i2c +); + +#ifdef __cplusplus +} +#endif + +#endif /*MSS_I2C_H_*/ diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/OLED/oled.c b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/OLED/oled.c new file mode 100644 index 000000000..e6b9d8e5c --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/OLED/oled.c @@ -0,0 +1,536 @@ +/***************************************************************************** + * (c) Copyright 2009 Actel Corporation. All rights reserved. + * + * Author : Actel Application Team + * Rev : 1.0.0.0 + * Description: Device driver for the on-board OLED for SmartFusion KITS + * Implementation of sample basic driver for OLED display found on Actel + * SmartFusion development boards. + * This code is intended as an example of using the SmartFusion I2C driver. + *****************************************************************************/ + + #include "oled.h" +#include "../bsp_config.h" + +/***************************************************************************//** + Command definitions for the SSD300 controller inside the OLED display module. + */ +#define CMD_DISPLAY_OFF_SET 0xD3 +#define CMD_PANEL_ON 0xAF +#define CMD_PANEL_OFF 0xAE +#define CMD_DC_DC 0xAD +#define CMD_DC_DC_DEFAULT_ON 0x8B +#define CMD_DC_DC_OFF 0x8A +#define CMD_DISPLAY_ALL_ON 0xA5 +#define CMD_DISPLAY_ALL_OFF 0xA4 +#define CMD_DISPLAY_NON_INV 0xA6 +#define CMD_DISPLAY_INV 0xA7 +#define CMD_ARECOL_LPM 0xD8 +#define CMD_ARECOL_MONO 0x00 +#define CMD_ARECOL_COLOR 0x30 +#define CMD_LPM_ON 0x05 +#define CMD_LPM_OFF 0x00 +#define CMD_CONTRAST 0x81 +#define CMD_MIRROR_HORI_ON 0xC8 +#define CMD_MIRROR_HORI_OFF 0xC0 +#define CMD_MIRROR_VERT_ON 0xA1 +#define CMD_MIRROR_VERT_OFF 0xA0 +#define CMD_HORI_SCRL 0x26 +#define CMD_HORI_SCRL_ON 0x2F +#define CMD_HORI_SCRL_OFF 0x2E +#define CMD_MUX_RATIO 0xA8 +#define CMD_MUX_RATIO_31 0x23 + +#define CMD_PAGE_0 0xB0 +#define CMD_PAGE_1 0xB1 +#define CMD_PAGE_2 0xB2 +#define CMD_PAGE_3 0xB3 +#define CMD_PAGE_4 0xB4 +#define CMD_PAGE_5 0xB5 + +#define CMD_LOW_NIB_COL 0x00 +#define CMD_HIGH_NIB_COL 0x10 + +#define CMD_START_LINE 0x50 +#define CONTRAST_DEFAULT 0xFF +#define CONTRAST_25_PERC 0x40 +#define CONTRAST_100_PERC 0xFF +#define CONTRAST_0_PERC 0x00 +#define SCROLL_1_COLUMN 0x01 +#define SCROLL_2_COLUMN 0x02 +#define SCROLL_3_COLUMN 0x03 +#define SCROLL_4_COLUMN 0x04 +#define SCROLL_PAGE_0 0x00 +#define SCROLL_PAGE_1 0x01 +#define SCROLL_PAGE_2 0x02 +#define SCROLL_PAGE_3 0x03 +#define SCROLL_PAGE_4 0x04 +#define SCROLL_PAGE_5 0x05 +#define SCROLL_12_FRAMES 0x00 +#define SCROLL_64_FRAMES 0x01 +#define SCROLL_128_FRAMES 0x02 +#define SCROLL_256_FRAMES 0x03 +#define SCROLL_PER_STEP 0x01 +#define PAGE0_COLOR_BAG 0x92 +#define PAGE1_COLOR_BAG 0x93 + +/***************************************************************************//** + OLED display I2C communication protocol control byte values. Used to indicate + whether the byte following the control byte is to be interpreted by the OLED + display as a command or data byte. + */ +#define OLED_COMMAND_CODE 0x80 +#define OLED_DATA_CODE 0xC0 + +/***************************************************************************//** + I2C serial address of OLED display. + */ +#define OLED_SLAVE_ADDRESS 0x78 + +/***************************************************************************//** + Bitmaps of the character set. + Each character is 5 pixels wide and 7 pixels high. + The table is indexed on ASCII character codes. + */ +#define CHARACTER_WIDTH 5 + +const unsigned char oled_ascii_character_set[255][CHARACTER_WIDTH] = +{ + {0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00}, + + {0x00, 0x00, 0x5F, 0x00, 0x00}, + {0x00, 0x07, 0x00, 0x07, 0x00}, + {0x14, 0x7F, 0x14, 0x7F, 0x14}, + {0x24, 0x2A, 0x7F, 0x2A, 0x12}, + {0x23, 0x13, 0x08, 0x64, 0x62}, + {0x36, 0x49, 0x55, 0x22, 0x50}, + {0x00, 0x05, 0x03, 0x00, 0x00}, + {0x00, 0x1C, 0x22, 0x41, 0x00}, + {0x00, 0x41, 0x22, 0x1C, 0x00}, + {0x14, 0x08, 0x3E, 0x08, 0x14}, + {0x08, 0x08, 0x3E, 0x08, 0x08}, + {0x00, 0x50, 0x30, 0x00, 0x00}, + {0x08, 0x08, 0x08, 0x08, 0x08}, + {0x00, 0x60, 0x60, 0x00, 0x00}, + {0x20, 0x10, 0x08, 0x04, 0x02}, + {0x3E, 0x51, 0x49, 0x45, 0x3E}, + {0x00, 0x42, 0x7F, 0x40, 0x00}, + {0x42, 0x61, 0x51, 0x49, 0x46}, + {0x21, 0x41, 0x45, 0x4B, 0x31}, + {0x18, 0x14, 0x12, 0x7F, 0x10}, + {0x27, 0x45, 0x45, 0x45, 0x39}, + {0x3C, 0x4A, 0x49, 0x49, 0x30}, + {0x01, 0x71, 0x09, 0x05, 0x03}, + {0x36, 0x49, 0x49, 0x49, 0x36}, + {0x06, 0x49, 0x49, 0x29, 0x1E}, + {0x00, 0x36, 0x36, 0x00, 0x00}, + {0x00, 0x56, 0x36, 0x00, 0x00}, + {0x08, 0x14, 0x22, 0x41, 0x00}, + {0x14, 0x14, 0x14, 0x14, 0x14}, + {0x00, 0x41, 0x22, 0x14, 0x08}, + {0x02, 0x01, 0x51, 0x09, 0x06}, + {0x32, 0x49, 0x79, 0x41, 0x3E}, + {0x7E, 0x11, 0x11, 0x11, 0x7E}, + {0x7F, 0x49, 0x49, 0x49, 0x36}, + {0x3E, 0x41, 0x41, 0x41, 0x22}, + {0x7F, 0x41, 0x41, 0x22, 0x1C}, + {0x7F, 0x49, 0x49, 0x49, 0x41}, + {0x7F, 0x09, 0x09, 0x09, 0x01}, + {0x3E, 0x41, 0x49, 0x49, 0x7A}, + {0x7F, 0x08, 0x08, 0x08, 0x7F}, + {0x00, 0x41, 0x7F, 0x41, 0x00}, + {0x20, 0x40, 0x41, 0x3F, 0x01}, + {0x7F, 0x08, 0x14, 0x22, 0x41}, + {0x3F, 0x40, 0x40, 0x40, 0x40}, + {0x7F, 0x02, 0x0C, 0x02, 0x7F}, + {0x7F, 0x04, 0x08, 0x10, 0x7F}, + {0x3E, 0x41, 0x41, 0x41, 0x3E}, + {0x7F, 0x09, 0x09, 0x09, 0x06}, + {0x3E, 0x41, 0x51, 0x21, 0x5E}, + {0x7F, 0x09, 0x19, 0x29, 0x46}, + {0x46, 0x49, 0x49, 0x49, 0x31}, + {0x01, 0x01, 0x7F, 0x01, 0x01}, + {0x3F, 0x40, 0x40, 0x40, 0x3F}, + {0x1F, 0x20, 0x40, 0x20, 0x1F}, + {0x3F, 0x40, 0x38, 0x40, 0x3F}, + {0x63, 0x14, 0x08, 0x14, 0x63}, + {0x07, 0x08, 0x70, 0x08, 0x07}, + {0x61, 0x51, 0x49, 0x45, 0x43}, + {0x00, 0x7F, 0x41, 0x41, 0x00}, + {0x02, 0x04, 0x08, 0x10, 0x20}, + {0x00, 0x41, 0x41, 0x7F, 0x00}, + {0x04, 0x02, 0x01, 0x02, 0x04}, + {0x40, 0x40, 0x40, 0x40, 0x40}, + {0x00, 0x01, 0x02, 0x04, 0x00}, + {0x20, 0x54, 0x54, 0x54, 0x78}, + {0x7F, 0x48, 0x44, 0x44, 0x38}, + {0x38, 0x44, 0x44, 0x44, 0x20}, + {0x30, 0x48, 0x48, 0x50, 0x7F}, + {0x38, 0x54, 0x54, 0x54, 0x18}, + {0x10, 0x7E, 0x11, 0x01, 0x02}, + {0x0C, 0x52, 0x52, 0x52, 0x3E}, + {0x7F, 0x08, 0x04, 0x04, 0x78}, + {0x00, 0x44, 0x7D, 0x40, 0x00}, + {0x20, 0x40, 0x44, 0x3D, 0x00}, + {0x7F, 0x10, 0x28, 0x44, 0x00}, + {0x00, 0x41, 0x7F, 0x40, 0x00}, + {0x7C, 0x04, 0x18, 0x04, 0x78}, + {0x7C, 0x08, 0x04, 0x04, 0x78}, + {0x38, 0x44, 0x44, 0x44, 0x38}, + {0x7C, 0x14, 0x14, 0x14, 0x08}, + {0x08, 0x14, 0x14, 0x18, 0x7C}, + {0x7C, 0x08, 0x04, 0x04, 0x08}, + {0x48, 0x54, 0x54, 0x54, 0x20}, + {0x04, 0x3F, 0x44, 0x40, 0x20}, + {0x3C, 0x40, 0x40, 0x20, 0x7C}, + {0x1C, 0x20, 0x40, 0x20, 0x1C}, + {0x3C, 0x40, 0x30, 0x40, 0x3C}, + {0x44, 0x28, 0x10, 0x28, 0x44}, + {0x0C, 0x50, 0x50, 0x50, 0x3C}, + {0x44, 0x64, 0x54, 0x4C, 0x44}, + + {0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00}, + + {0x07, 0x05, 0x07, 0x00, 0x00}, + {0x12, 0x19, 0x16, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00} + +}; + +#define FIRST_CHARACTER 0 + +/***************************************************************************//** + The g_p_oled_i2c global variable is only used inside the OLED driver. It + identifies the MSS I2C block used to communicate with the OLED display. + */ +static mss_i2c_instance_t * g_p_oled_i2c = OLED_I2C_INSTANCE; + +/***************************************************************************//** + The OLED_set_cursor function sets the cursor position. + + @param line + The line parameter specifies the line at which to set the cursor. It can + take the values: + - FIRST_LINE + - SECOND_LINE + + @param char_offset + The char_offset paraemter specifies the character offset on a line where to + set the cursor location. It can be set to FIRST_CHARACTER to set the cursor + at the start of a line. + */ +void OLED_set_cursor +( + uint8_t line, + uint8_t char_offset +); +/***************************************************************************//** + The OLED_write_string function displays the input string to the OLED panel. + + @param string + The string parameter is a pointer to the zero-terminated to display on the + OLED. + */ +void OLED_write_string( const char *string); + +/***************************************************************************//** + The OLED_write_char function displays a single character to the display. + + @param data_char + The data_char parameter is the ASCII code of the character to display. +*/ +void OLED_write_char( const uint8_t data_char ); +/***************************************************************************//** + OLED_init() + See "oled.h" for details of how to use this function. + */ +void OLED_init(void ) +{ + uint8_t oled_init_sequence1[] = + { + OLED_COMMAND_CODE, CMD_DISPLAY_NON_INV, + OLED_COMMAND_CODE, CMD_DISPLAY_ALL_OFF, + OLED_COMMAND_CODE, CMD_MIRROR_HORI_ON, + OLED_COMMAND_CODE, CMD_MIRROR_VERT_OFF, + OLED_COMMAND_CODE, CMD_HORI_SCRL_OFF, + OLED_COMMAND_CODE, CMD_CONTRAST, + OLED_COMMAND_CODE, CONTRAST_DEFAULT, + OLED_COMMAND_CODE, CMD_ARECOL_LPM, + OLED_COMMAND_CODE, CMD_ARECOL_MONO^CMD_LPM_OFF + }; + + uint8_t oled_init_sequence2[] = + { + OLED_COMMAND_CODE, CMD_START_LINE, + OLED_COMMAND_CODE, CMD_PANEL_ON + }; + + MSS_I2C_init( g_p_oled_i2c, OLED_SLAVE_ADDRESS, MSS_I2C_PCLK_DIV_60 ); + + MSS_I2C_write( g_p_oled_i2c, OLED_SLAVE_ADDRESS, oled_init_sequence1, sizeof(oled_init_sequence1), MSS_I2C_RELEASE_BUS ); + MSS_I2C_wait_complete( g_p_oled_i2c ); + + OLED_clear_display(BOTH_LINES); + + MSS_I2C_write( g_p_oled_i2c, OLED_SLAVE_ADDRESS, oled_init_sequence2, sizeof(oled_init_sequence2), MSS_I2C_RELEASE_BUS ); + MSS_I2C_wait_complete( g_p_oled_i2c ); + + OLED_set_cursor( FIRST_LINE, FIRST_CHARACTER ); +} + +/***************************************************************************//** + OLED_clear_display() + See "oled.h" for details of how to use this function. + */ +void OLED_clear_display( oled_no_of_line LINES ) +{ + uint8_t i, j,start_line,end_line; + uint8_t clear_8_columns[] = + { + OLED_DATA_CODE, 0x00, + OLED_DATA_CODE, 0x00, + OLED_DATA_CODE, 0x00, + OLED_DATA_CODE, 0x00, + OLED_DATA_CODE, 0x00, + OLED_DATA_CODE, 0x00, + OLED_DATA_CODE, 0x00, + OLED_DATA_CODE, 0x00 + }; + + switch(LINES) + { + case FIRST_LINE: + { + start_line = FIRST_LINE; + end_line = FIRST_LINE; + } + + case SECOND_LINE: + { + start_line = SECOND_LINE; + end_line = SECOND_LINE; + } + + case BOTH_LINES: + { + start_line = FIRST_LINE; + end_line = SECOND_LINE; + } + + } + + for( j = start_line; j <= end_line; ++j ) + { + OLED_set_cursor( j, FIRST_CHARACTER ); + for( i = 0; i < 13; ++i ) + { + MSS_I2C_write( g_p_oled_i2c, OLED_SLAVE_ADDRESS, clear_8_columns, sizeof(clear_8_columns), MSS_I2C_RELEASE_BUS ); + MSS_I2C_wait_complete( g_p_oled_i2c ); + } + } +} + +/***************************************************************************//** + OLED_set_cursor() + See definition of OLED_set_cursor() for details of how to use this function. + */ +void OLED_set_cursor +( + uint8_t line, + uint8_t char_offset +) +{ + uint8_t command_sequence[] = + { + OLED_COMMAND_CODE, CMD_LOW_NIB_COL, + OLED_COMMAND_CODE, CMD_HIGH_NIB_COL, + OLED_COMMAND_CODE, CMD_PAGE_0 + }; + uint8_t low_nib, high_nib; + + ++char_offset; + char_offset *= CHARACTER_WIDTH; + low_nib = 0x0F & char_offset; + high_nib = (0xF0 & char_offset) >> 4; + line += 2; + + command_sequence[1] |= low_nib; + command_sequence[3] |= high_nib; + command_sequence[5] |= line; + MSS_I2C_write( g_p_oled_i2c, OLED_SLAVE_ADDRESS, command_sequence, sizeof(command_sequence), MSS_I2C_RELEASE_BUS ); + MSS_I2C_wait_complete( g_p_oled_i2c ); +} + +/***************************************************************************//** + OLED_write_string() + See definition of OLED_write_string for details of how to use this function. + */ +void OLED_write_string +( + const char *string +) +{ + while (*string != 0) + { + OLED_write_char( *string ); + ++string; + } +} + +/***************************************************************************//** + OLED_write_char() + See definition of OLED_write_char() for details of how to use this function. + */ +void OLED_write_char +( + const uint8_t data_char +) +{ + uint8_t txbuff[10]; + uint8_t i; + + for ( i = 0; i < CHARACTER_WIDTH; ++i ) + { + txbuff[i * 2] = OLED_DATA_CODE; + txbuff[(i * 2) + 1] = oled_ascii_character_set[data_char][i]; + } + MSS_I2C_write( g_p_oled_i2c, OLED_SLAVE_ADDRESS, txbuff, sizeof(txbuff), MSS_I2C_RELEASE_BUS ); + MSS_I2C_wait_complete( g_p_oled_i2c ); +} + +/***************************************************************************//** + OLED_horizontal_scroll() + See "oled.h" for details of how to use this function. + */ +void OLED_horizontal_scroll(struct oled_data * horiz_scroll) +{ + uint8_t horiz_scroll_on_off[] = + { + OLED_COMMAND_CODE, CMD_HORI_SCRL_OFF, + }; + + uint8_t horiz_scroll_setup_data[] = + { + OLED_COMMAND_CODE, CMD_HORI_SCRL, + OLED_COMMAND_CODE, SCROLL_PER_STEP, + OLED_COMMAND_CODE, SCROLL_PAGE_0, + OLED_COMMAND_CODE, SCROLL_12_FRAMES, + OLED_COMMAND_CODE, SCROLL_PAGE_1, + }; + MSS_I2C_write( g_p_oled_i2c, OLED_SLAVE_ADDRESS, horiz_scroll_on_off, sizeof(horiz_scroll_on_off), MSS_I2C_RELEASE_BUS ); + MSS_I2C_wait_complete( g_p_oled_i2c ); + + if(horiz_scroll->on_off == 1) + { + horiz_scroll_setup_data[3] = horiz_scroll->column_scrool_per_step; + horiz_scroll_setup_data[5] = horiz_scroll->start_page; + horiz_scroll_setup_data[7] = horiz_scroll->time_intrval_btw_scroll_step; + horiz_scroll_setup_data[9] = horiz_scroll->end_page; + MSS_I2C_write( g_p_oled_i2c, OLED_SLAVE_ADDRESS, horiz_scroll_setup_data, sizeof(horiz_scroll_setup_data), MSS_I2C_RELEASE_BUS ); + MSS_I2C_wait_complete( g_p_oled_i2c ); + + horiz_scroll_on_off[1] = CMD_HORI_SCRL_ON; + MSS_I2C_write( g_p_oled_i2c, OLED_SLAVE_ADDRESS, horiz_scroll_on_off, sizeof(horiz_scroll_on_off), MSS_I2C_RELEASE_BUS ); + MSS_I2C_wait_complete( g_p_oled_i2c ); + } +} + +/***************************************************************************//** + OLED_contrast() + See "oled.h" for details of how to use this function. + */ +void OLED_contrast(uint8_t color_contrast) +{ + uint8_t oled_contrast[] = + { + OLED_COMMAND_CODE, CMD_CONTRAST, + OLED_COMMAND_CODE, CONTRAST_DEFAULT, + }; + + oled_contrast[3] = color_contrast; + MSS_I2C_write( g_p_oled_i2c, OLED_SLAVE_ADDRESS, oled_contrast, sizeof(oled_contrast), MSS_I2C_RELEASE_BUS ); + MSS_I2C_wait_complete( g_p_oled_i2c ); + +} + +/***************************************************************************//** + OLED_write_data() + See "oled.h" for details of how to use this function. + */ +void OLED_write_data(struct oled_data* data, oled_no_of_line LINES) +{ + uint8_t line; + uint8_t char_offset; + char *string; + + switch(LINES) + { + + case FIRST_LINE: + { + OLED_clear_display(FIRST_LINE); + line = data->line1; + char_offset = data->char_offset1; + string = data->string1; + } + + case SECOND_LINE: + { + OLED_clear_display(SECOND_LINE); + line = data->line2; + char_offset = data->char_offset2; + string = data->string2; + } + + case BOTH_LINES: + { + OLED_clear_display(BOTH_LINES); + line = data->line1; + char_offset = data->char_offset1; + string = data->string1; + OLED_set_cursor(line,char_offset); + OLED_write_string(string); + line = data->line2; + char_offset = data->char_offset2; + string = data->string2; + } + + OLED_set_cursor(line,char_offset); + OLED_write_string(string); + OLED_contrast(data->contrast_val); + } +} diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/OLED/oled.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/OLED/oled.h new file mode 100644 index 000000000..17ab4a71c --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/OLED/oled.h @@ -0,0 +1,210 @@ +/***************************************************************************** + * (c) Copyright 2009 Actel Corporation. All rights reserved. + * + * Author : Actel Application Team + * Rev : 1.0.0.0 + * Description: Device driver for the on-board OLED for SmartFusion KITS + * API of sample basic driver for OLED display found on Actel SmartFusion + * development boards. + * This code is intended as an example of using the SmartFusion I2C driver. + * + */ +#ifndef OLED_H_ +#define OLED_H_ + +#include "i2c.h" + +#define OLED_HORIZ_SCROLL_ON 0x01 +#define OLED_HORIZ_SCROLL_OFF 0x00 +#define OLED_HORIZ_SCROLL_STEP 0x08 +#define OLED_CONTRAST_VAL 0xFF +#define OLED_START_PAGE 0x01 +#define OLED_HORIZ_SCROLL_TINVL 0x00 +#define OLED_END_PAGE 0x05 +/*-------------------------------------------------------------------------*/ +/* The oled_no_of_line type represents number of lines to be written on OLED. + FIRST LINE : The OLED cursor is set to line number 1 and only 1 line is + printed on OLED + SECOND_LINE : The OLED cursor is set to line number 2 and only 1 line is + printed on OLED + BOTH_LINES : The OLED cursor is set to line number 1 and line 1 and line 2 + are printed on OLED +*/ +typedef enum { + FIRST_LINE = 0, + SECOND_LINE, + BOTH_LINES +} oled_no_of_line; + +/*-------------------------------------------------------------------------*//** + oled_data + ------------------------------------------------------------------------------ + There is one instance of this structure for OLED data. Instances of this + structure is used to provide the data to OLED. A pointer to an instance of + the oled_data structure is passed as the parameter OLED driver functions. + */ +struct oled_data +{ + /* Represents line number, where String 1 has to be printed */ + uint8_t line1; + /* Represents character offset within the line1, from where String 1 has to be + * printed */ + uint8_t char_offset1; + /* Represents line number, where String 2 has to be printed */ + uint8_t line2; + /* Represents character offset within the line2, from where String 2 has to be + * printed */ + uint8_t char_offset2; + /* String 1 holds the data to be displayed on line 1 of OLED, It has to be + * less that 49 characters*/ + char *string1; + /* String 1 holds the data to be displayed on line 2 of OLED, It has to be + * less that 49 characters*/ + char *string2; + /* Holds the contrast value to be set for String 1 and String 2 */ + uint8_t contrast_val; + /* Represents ON or OFF for horizontal scrolling */ + uint8_t on_off; + /* Represents number of coumns scrolls per step for horizontal scroll*/ + unsigned char column_scrool_per_step; + /* Represents start page for horizontal scroll*/ + unsigned char start_page; + /* Represents time interval for horizontal scroll*/ + unsigned char time_intrval_btw_scroll_step; + /* Represents end page for horizontal scroll*/ + unsigned char end_page; + +}; +/***************************************************************************//** + The following defines can be used as parameter to the OLED_set_cursor() + function. + */ + +/***************************************************************************//** + The OLED_init function initializes the OLED display. + */ +void vOLEDInit( void ); +void OLED_init( void ); + +/***************************************************************************//** + This function(OLED_clear_display) clears the content of the display RAM + based on the LINES input. + ------------------------------------------------------------------------------ + @param oled_no_of_line: + The oled_no_of_line parameter enum that holds Number of lines. + If FIRST_LINE is passed as parameter to this function thnen, this functions + clears only First line that is 0 + If SECOND_LINE is passed as parameter to this function thnen, this functions + clears only Second line that is 1 + If BOTH_LINE is passed as parameter to this function thnen, this functions + clears entire OLED display. + */ +void OLED_clear_display( oled_no_of_line LINES ); + +/*-------------------------------------------------------------------------*//** + OLED Write data. + ------------------------------------------------------------------------------ + This function (OLED_write_data ) writes the data to OLED basedon the + parameters passed to this function. + ------------------------------------------------------------------------------ + @param data: + The data parameter is a pointer to an oled_data structure, that holds + different fields of data to be required for OLED (see the oled_data structure + definition). + + @param oled_no_of_line: + The oled_no_of_line parameter enum that holds Number of lines. + If FIRST_LINE is passed as parameter to this function thnen, this functions + wtites string 1 at FIRST LINE + If SECOND_LINE is passed as parameter to this function thnen, this functions + wtites string 1 at SECOND LINE + If BOTH_LINE is passed as parameter to this function thnen, this functions + wtites string 1 and string 2 at FIRST LINE and SECOND LINE respectively. +Example: + @code +#include "drivers/mss_watchdog/mss_watchdog.h" +#include "oled.h" +#define FIRST_CHARACTER 0 + +int main() +{ + + char *string1="SmartFusion"; + char *string2="INNOVATIVE "; + struct oled_data write_data; + + write_data.line1 = FIRST_LINE; + write_data.char_offset1 = FIRST_CHARACTER; + write_data.string1 = string1; + write_data.line2 = SECOND_LINE; + write_data.char_offset2 = FIRST_CHARACTER; + write_data.string2 = string2; + write_data.contrast_val = 0x01; + + MSS_WD_disable(); + OLED_init(); + OLED_write_data(&write_data,BOTH_LINES); + return 0; +} + @endcode + */ + +void OLED_write_data(struct oled_data * data, oled_no_of_line flag); + +/*-------------------------------------------------------------------------*//** + OLED Horizontal scrolling. + ------------------------------------------------------------------------------ + This function (OLED_horizontal_scroll ) enbles the Horizontal scrolling. + ------------------------------------------------------------------------------ + @param data: + The horiz_scroll parameter is a pointer to an oled_data structure, that holds + different fields of data to be required for OLED (see the oled_data structure + definition). +Example: + @code + +int main() +{ + + char *string1="SmartFusion"; + char *string2="INNOVATIVE "; + struct oled_data write_data; + + write_data.line1 = FIRST_LINE; + write_data.char_offset1 = FIRST_CHARACTER; + write_data.string1 = string1; + write_data.line2 = SECOND_LINE; + write_data.char_offset2 = FIRST_CHARACTER; + write_data.string2 = string2; + write_data.contrast_val = 0x01; + write_data.on_off = 0x01; + write_data.column_scrool_per_step = 0x08; + write_data.start_page = 0x01; + write_data.time_intrval_btw_scroll_step = 0x00; + write_data.end_page = 0x05; + + MSS_WD_disable(); + OLED_init(); + OLED_write_data(&write_data,BOTH_LINES); + OLED_horizontal_scroll(&write_data); + return 0; +} + @endcode + */ + +void OLED_horizontal_scroll(struct oled_data * horiz_scroll); + +/***************************************************************************//** + This function(OLED_contrast) sets ths conrtast to the data displayed on the + OLED. + ------------------------------------------------------------------------------ + @param color_contrast: + The color_contrast parameter that holds contrast value. + The color_contrast values should be in the range of 1 to 256. + */ +void OLED_contrast(uint8_t color_contrast); + +#endif + + + diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/bsp_config.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/bsp_config.h new file mode 100644 index 000000000..79f456e1a --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/bsp_config.h @@ -0,0 +1,28 @@ +/***************************************************************************** + * (c) Copyright 2009 Actel Corporation. All rights reserved. + * + * + * + * Author : Actel Application Team + * Rev : 1.0.0.0 + * Description: Configuration for the ON-BOARD peripherals for SmartFusion KITS. + * + *******************************************************************************/ +#ifndef BSP_CONFIG_H_ +#define BSP_CONFIG_H_ + +#include "i2c.h" +/* Configuration for OLED */ +#define OLED_I2C_INSTANCE &g_mss_i2c0 + +/* Configuration for the SPI Flash */ +#define SPI_FLASH_ON_SF_DEV_KIT 0 +#define SPI_FLASH_ON_SF_EVAL_KIT 1 + +#define USE_DMA_FOR_SPI_FLASH 1 +#define SPI_FLASH_DMA_CHANNEL 0 + +#endif + + + diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/ace_convert.c b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/ace_convert.c new file mode 100644 index 000000000..dbe1205ba --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/ace_convert.c @@ -0,0 +1,831 @@ +/******************************************************************************* + * (c) Copyright 2009 Actel Corporation. All rights reserved. + * + * SVN $Revision: 2905 $ + * SVN $Date: 2010-08-20 14:03:28 +0100 (Fri, 20 Aug 2010) $ + */ +#include "mss_ace.h" +#include "mss_ace_configurator.h" +#include "../../CMSIS/a2fxxxm3.h" +#include "../../CMSIS/mss_assert.h" +#include "../../drivers_config/mss_ace/ace_handles.h" +#include "../../drivers_config/mss_ace/ace_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*-------------------------------------------------------------------------*//** + * + */ +extern ace_channel_desc_t g_ace_channel_desc_table[ACE_NB_OF_INPUT_CHANNELS]; +extern ace_adc_config_t g_ace_adc_config[ACE_NB_OF_ADC]; +extern const uint32_t g_ace_current_resistors[ACE_NB_OF_CURRENT_MONITORS]; + +/*-------------------------------------------------------------------------*//** + * + */ +static uint16_t convert_mV_to_ppe_value +( + ace_channel_handle_t channel_handle, + uint32_t voltage +); + +/*-------------------------------------------------------------------------*//** + * + */ +void ace_init_convert(void); + +/*-------------------------------------------------------------------------*//** + * + */ +#define VOLTAGE_CHANNEL 0u +#define CURRENT_CHANNEL 1u +#define TEMPERATURE_CHANNEL 2u +#define INVALID_CHANNEL 0xFFu + +static const uint8_t channel_type_lut[] = +{ + VOLTAGE_CHANNEL, /* ADC0_1P5V = 0 */ + VOLTAGE_CHANNEL, /* ABPS0 = 1 */ + VOLTAGE_CHANNEL, /* ABPS1 = 2 */ + CURRENT_CHANNEL, /* CM0 = 3 */ + TEMPERATURE_CHANNEL, /* TM0 = 4 */ + VOLTAGE_CHANNEL, /* ABPS2 = 5 */ + VOLTAGE_CHANNEL, /* ABPS3 = 6 */ + CURRENT_CHANNEL, /* CM1 = 7 */ + TEMPERATURE_CHANNEL, /* TM1 = 8 */ + VOLTAGE_CHANNEL, /* ADC0 = 9 */ + VOLTAGE_CHANNEL, /* ADC1 = 10 */ + VOLTAGE_CHANNEL, /* ADC2 = 11 */ + VOLTAGE_CHANNEL, /* ADC3 = 12 */ + INVALID_CHANNEL, + INVALID_CHANNEL, + VOLTAGE_CHANNEL, /* SDD0_IN = 15 */ + + VOLTAGE_CHANNEL, /* ADC1_1P5V = 16 */ + VOLTAGE_CHANNEL, /* ABPS4 = 17 */ + VOLTAGE_CHANNEL, /* ABPS5 = 18 */ + CURRENT_CHANNEL, /* CM2 = 19 */ + TEMPERATURE_CHANNEL, /* TM2 = 20 */ + VOLTAGE_CHANNEL, /* ABPS6 = 21 */ + VOLTAGE_CHANNEL, /* ABPS7 = 22 */ + CURRENT_CHANNEL, /* CM3 = 23 */ + TEMPERATURE_CHANNEL, /* TM3 = 24 */ + VOLTAGE_CHANNEL, /* ADC4 = 25 */ + VOLTAGE_CHANNEL, /* ADC5 = 26 */ + VOLTAGE_CHANNEL, /* ADC6 = 27 */ + VOLTAGE_CHANNEL, /* ADC7 = 28 */ + INVALID_CHANNEL, + INVALID_CHANNEL, + VOLTAGE_CHANNEL, /* SDD1_IN = 31 */ + + VOLTAGE_CHANNEL, /* ADC2_1P5V = 32 */ + VOLTAGE_CHANNEL, /* ABPS8 = 33 */ + VOLTAGE_CHANNEL, /* ABPS9 = 34 */ + CURRENT_CHANNEL, /* CM4 = 35 */ + TEMPERATURE_CHANNEL, /* TM4 = 36 */ + VOLTAGE_CHANNEL, /* ABPS10 = 37 */ + VOLTAGE_CHANNEL, /* ABPS11 = 38 */ + CURRENT_CHANNEL, /* CM5 = 39 */ + TEMPERATURE_CHANNEL, /* TM5 = 40 */ + VOLTAGE_CHANNEL, /* ADC8 = 41 */ + VOLTAGE_CHANNEL, /* ADC9 = 42 */ + VOLTAGE_CHANNEL, /* ADC10 = 43 */ + VOLTAGE_CHANNEL, /* ADC11 = 44 */ + INVALID_CHANNEL, + INVALID_CHANNEL, + VOLTAGE_CHANNEL /* SDD2_IN = 47 */ +}; + +static const uint8_t channel_quad_lut[] = +{ + 0xFFu, /* ADC0_1P5V = 0 */ + 0u, /* ABPS0 = 1 */ + 0u, /* ABPS1 = 2 */ + 0u, /* CM0 = 3 */ + 0u, /* TM0 = 4 */ + 1u, /* ABPS2 = 5 */ + 1u, /* ABPS3 = 6 */ + 1u, /* CM1 = 7 */ + 1u, /* TM1 = 8 */ + 0xFFu, /* ADC0 = 9 */ + 0xFFu, /* ADC1 = 10 */ + 0xFFu, /* ADC2 = 11 */ + 0xFFu, /* ADC3 = 12 */ + INVALID_CHANNEL, + INVALID_CHANNEL, + 0xFFu, /* SDD0_IN = 15 */ + + 0xFFu, /* ADC1_1P5V = 16 */ + 2u, /* ABPS4 = 17 */ + 2u, /* ABPS5 = 18 */ + 2u, /* CM2 = 19 */ + 2u, /* TM2 = 20 */ + 3u, /* ABPS6 = 21 */ + 3u, /* ABPS7 = 22 */ + 3u, /* CM3 = 23 */ + 3u, /* TM3 = 24 */ + 0xFFu, /* ADC4 = 25 */ + 0xFFu, /* ADC5 = 26 */ + 0xFFu, /* ADC6 = 27 */ + 0xFFu, /* ADC7 = 28 */ + INVALID_CHANNEL, + INVALID_CHANNEL, + 0xFFu, /* SDD1_IN = 31 */ + + 0xFFu, /* ADC2_1P5V = 32 */ + 4u, /* ABPS8 = 33 */ + 4u, /* ABPS9 = 34 */ + 4u, /* CM4 = 35 */ + 4u, /* TM4 = 36 */ + 5u, /* ABPS10 = 37 */ + 5u, /* ABPS11 = 38 */ + 5u, /* CM5 = 39 */ + 5u, /* TM5 = 40 */ + 0xFFu, /* ADC8 = 41 */ + 0xFFu, /* ADC9 = 42 */ + 0xFFu, /* ADC10 = 43 */ + 0xFFu, /* ADC11 = 44 */ + INVALID_CHANNEL, + INVALID_CHANNEL, + 0xFFu /* SDD2_IN = 47 */ +}; + +/*-------------------------------------------------------------------------*//** + * + */ +#define NON_ABPS_CHANNEL 0xFFu +#define MAX_NB_OF_APBS 12u + +/*-------------------------------------------------------------------------*//** + * Lookup of the quad to which an ABPS belongs + */ +static const uint8_t abps_channel_lut[] = +{ + NON_ABPS_CHANNEL, /* ADC0_1P5V = 0 */ + 0u, /* ABPS0 = 1 */ + 0u, /* ABPS1 = 2 */ + NON_ABPS_CHANNEL, /* CM0 = 3 */ + NON_ABPS_CHANNEL, /* TM0 = 4 */ + 1u, /* ABPS2 = 5 */ + 1u, /* ABPS3 = 6 */ + NON_ABPS_CHANNEL, /* CM1 = 7 */ + NON_ABPS_CHANNEL, /* TM1 = 8 */ + NON_ABPS_CHANNEL, /* ADC0 = 9 */ + NON_ABPS_CHANNEL, /* ADC1 = 10 */ + NON_ABPS_CHANNEL, /* ADC2 = 11 */ + NON_ABPS_CHANNEL, /* ADC3 = 12 */ + INVALID_CHANNEL, + INVALID_CHANNEL, + NON_ABPS_CHANNEL, /* SDD0_IN = 15 */ + + NON_ABPS_CHANNEL, /* ADC1_1P5V = 16 */ + 2u, /* ABPS4 = 17 */ + 2u, /* ABPS5 = 18 */ + NON_ABPS_CHANNEL, /* CM2 = 19 */ + NON_ABPS_CHANNEL, /* TM2 = 20 */ + 3u, /* ABPS6 = 21 */ + 3u, /* ABPS7 = 22 */ + NON_ABPS_CHANNEL, /* CM3 = 23 */ + NON_ABPS_CHANNEL, /* TM3 = 24 */ + NON_ABPS_CHANNEL, /* ADC4 = 25 */ + NON_ABPS_CHANNEL, /* ADC5 = 26 */ + NON_ABPS_CHANNEL, /* ADC6 = 27 */ + NON_ABPS_CHANNEL, /* ADC7 = 28 */ + INVALID_CHANNEL, + INVALID_CHANNEL, + NON_ABPS_CHANNEL, /* SDD1_IN = 31 */ + + NON_ABPS_CHANNEL, /* ADC2_1P5V = 32 */ + 4u, /* ABPS8 = 33 */ + 4u, /* ABPS9 = 34 */ + NON_ABPS_CHANNEL, /* CM4 = 35 */ + NON_ABPS_CHANNEL, /* TM4 = 36 */ + 5u, /* ABPS10 = 37 */ + 5u, /* ABPS11 = 38 */ + NON_ABPS_CHANNEL, /* CM5 = 39 */ + NON_ABPS_CHANNEL, /* TM5 = 40 */ + NON_ABPS_CHANNEL, /* ADC8 = 41 */ + NON_ABPS_CHANNEL, /* ADC9 = 42 */ + NON_ABPS_CHANNEL, /* ADC10 = 43 */ + NON_ABPS_CHANNEL, /* ADC11 = 44 */ + INVALID_CHANNEL, + INVALID_CHANNEL, + NON_ABPS_CHANNEL /* SDD2_IN = 47 */ +}; + +static const uint8_t abps_idx_lut[] = +{ + NON_ABPS_CHANNEL, /* ADC0_1P5V = 0 */ + 0u, /* ABPS0 = 1 */ + 1u, /* ABPS1 = 2 */ + NON_ABPS_CHANNEL, /* CM0 = 3 */ + NON_ABPS_CHANNEL, /* TM0 = 4 */ + 2u, /* ABPS2 = 5 */ + 3u, /* ABPS3 = 6 */ + NON_ABPS_CHANNEL, /* CM1 = 7 */ + NON_ABPS_CHANNEL, /* TM1 = 8 */ + NON_ABPS_CHANNEL, /* ADC0 = 9 */ + NON_ABPS_CHANNEL, /* ADC1 = 10 */ + NON_ABPS_CHANNEL, /* ADC2 = 11 */ + NON_ABPS_CHANNEL, /* ADC3 = 12 */ + INVALID_CHANNEL, + INVALID_CHANNEL, + NON_ABPS_CHANNEL, /* SDD0_IN = 15 */ + + NON_ABPS_CHANNEL, /* ADC1_1P5V = 16 */ + 4u, /* ABPS4 = 17 */ + 5u, /* ABPS5 = 18 */ + NON_ABPS_CHANNEL, /* CM2 = 19 */ + NON_ABPS_CHANNEL, /* TM2 = 20 */ + 6u, /* ABPS6 = 21 */ + 7u, /* ABPS7 = 22 */ + NON_ABPS_CHANNEL, /* CM3 = 23 */ + NON_ABPS_CHANNEL, /* TM3 = 24 */ + NON_ABPS_CHANNEL, /* ADC4 = 25 */ + NON_ABPS_CHANNEL, /* ADC5 = 26 */ + NON_ABPS_CHANNEL, /* ADC6 = 27 */ + NON_ABPS_CHANNEL, /* ADC7 = 28 */ + INVALID_CHANNEL, + INVALID_CHANNEL, + NON_ABPS_CHANNEL, /* SDD1_IN = 31 */ + + NON_ABPS_CHANNEL, /* ADC2_1P5V = 32 */ + 8u, /* ABPS8 = 33 */ + 9u, /* ABPS9 = 34 */ + NON_ABPS_CHANNEL, /* CM4 = 35 */ + NON_ABPS_CHANNEL, /* TM4 = 36 */ + 10u, /* ABPS10 = 37 */ + 11u, /* ABPS11 = 38 */ + NON_ABPS_CHANNEL, /* CM5 = 39 */ + NON_ABPS_CHANNEL, /* TM5 = 40 */ + NON_ABPS_CHANNEL, /* ADC8 = 41 */ + NON_ABPS_CHANNEL, /* ADC9 = 42 */ + NON_ABPS_CHANNEL, /* ADC10 = 43 */ + NON_ABPS_CHANNEL, /* ADC11 = 44 */ + INVALID_CHANNEL, + INVALID_CHANNEL, + NON_ABPS_CHANNEL /* SDD2_IN = 47 */ +}; + +/*-------------------------------------------------------------------------*//** + * + */ +static const int8_t apbs_gain_lut[] = +{ + 12, + 8, + 4, + 2 +}; + +static const int16_t apbs_range[] = +{ + 15360, + 10240, + 5120, + 2560 +}; + +static uint8_t g_gdec_lut[MAX_NB_OF_APBS]; +static channel_type_t channel_type_lut_h[ACE_NB_OF_INPUT_CHANNELS]; + + +/*-------------------------------------------------------------------------*//** + * + */ +channel_type_t +ACE_get_channel_type +( + ace_channel_handle_t channel_handle +) +{ + channel_type_t channel_type = VOLTAGE; + + ASSERT(channel_handle < ACE_NB_OF_INPUT_CHANNELS); + + if((int32_t)channel_handle < ACE_NB_OF_INPUT_CHANNELS) + { + channel_type = channel_type_lut_h[channel_handle]; + } + else + { + channel_type = VOLTAGE; + } + + return channel_type; +} + +/*-------------------------------------------------------------------------*//** + * + */ +uint32_t ACE_convert_adc_input_to_mV +( + ace_channel_handle_t channel_handle, + uint16_t sample_value +) +{ + uint32_t voltage; + adc_channel_id_t channel_id; + uint8_t adc_id; + + channel_id = g_ace_channel_desc_table[channel_handle].signal_id; + adc_id = (uint8_t)channel_id >> 4u; + voltage = ( g_ace_adc_config[adc_id].va_ref * (uint32_t)sample_value ) / g_ace_adc_config[adc_id].adc_resolution; + + return voltage; +} + +/*-------------------------------------------------------------------------*//** + * + */ +#define PPE_SAMPLES_RESOLUTION 4095u + +/*-------------------------------------------------------------------------*//** + * + */ +void ace_init_convert(void) +{ + uint8_t abps_idx; + int32_t channel; + uint32_t saved_pc2_ctrl; + + /* Pause the SSE PC2 while accesses to ACB from APB3 are taking place. */ + saved_pc2_ctrl = ACE->PC2_CTRL; + ACE->PC2_CTRL = 0u; + + /* Populate the g_gdec_lut look-up table. */ + for(abps_idx = 0u; abps_idx < MAX_NB_OF_APBS; ++abps_idx) + { + uint8_t quad_id; + uint8_t acb_config_byte; + uint32_t channel_is_abps2; + + quad_id = abps_idx / 2u; + acb_config_byte = ACE->ACB_DATA[quad_id].b8; + channel_is_abps2 = abps_idx & 0x01uL; + if(channel_is_abps2) + { + /* ABPS2 */ + g_gdec_lut[abps_idx] = (acb_config_byte >> 5u) & 0x03u; + } + else + { + /* ABPS1 */ + g_gdec_lut[abps_idx] = (acb_config_byte >> 1u) & 0x03u; + } + } + + /* Populate the channel_type_lut_h look-up table. */ + for(channel = 0; channel < ACE_NB_OF_INPUT_CHANNELS; ++channel) + { + uint8_t quad_id; + uint8_t acb_config_byte; + adc_channel_id_t channel_id; + channel_type_t channel_type; + + channel_id = g_ace_channel_desc_table[channel].signal_id; + quad_id = channel_quad_lut[channel_id]; + + switch (channel_type_lut[channel_id]) + { + case VOLTAGE_CHANNEL: + channel_type = VOLTAGE; + break; + + case CURRENT_CHANNEL: + ASSERT( quad_id != 0xFFu ); + acb_config_byte = ACE->ACB_DATA[quad_id].b9; + if ( acb_config_byte & 0x01u ) + { + channel_type = VOLTAGE; + } + else + { + channel_type = CURRENT; + } + break; + + case TEMPERATURE_CHANNEL: + ASSERT( quad_id != 0xFFu ); + acb_config_byte = ACE->ACB_DATA[quad_id].b10; + if ( acb_config_byte & 0x01u ) + { + channel_type = VOLTAGE; + } + else + { + channel_type = TEMPERATURE; + } + break; + + default: + ASSERT(0); + channel_type = VOLTAGE; + break; + } + + channel_type_lut_h[channel] = channel_type; + } + + /* Restore SSE PC2 operations. */ + ACE->PC2_CTRL = saved_pc2_ctrl; +} + +/*-------------------------------------------------------------------------*//** + * + */ +int32_t ACE_convert_to_mV +( + ace_channel_handle_t channel_handle, + uint16_t sample_value +) +{ + uint32_t adc_voltage; + int32_t voltage; + adc_channel_id_t channel_id; + uint8_t adc_id; + uint8_t apbs_idx; + + channel_id = g_ace_channel_desc_table[channel_handle].signal_id; + adc_id = (uint8_t)channel_id >> 4u; + adc_voltage = ( g_ace_adc_config[adc_id].va_ref * (uint32_t)sample_value ) / PPE_SAMPLES_RESOLUTION; + voltage = (int32_t)adc_voltage; + + apbs_idx = abps_idx_lut[channel_id]; + if ( abps_channel_lut[channel_id] != NON_ABPS_CHANNEL ) + { + uint8_t gdec; + gdec = g_gdec_lut[apbs_idx]; + voltage = (voltage * apbs_gain_lut[gdec]) - apbs_range[gdec]; + } + return voltage; +} + +/*-------------------------------------------------------------------------*//** + * + */ +uint32_t ACE_convert_to_mA +( + ace_channel_handle_t channel_handle, + uint16_t sample_value +) +{ + uint32_t current = 0u; + + ASSERT(channel_handle < ACE_NB_OF_INPUT_CHANNELS); + + if((int32_t)channel_handle < ACE_NB_OF_INPUT_CHANNELS) + { + adc_channel_id_t channel_id; + uint8_t current_monitor_idx; + + channel_id = g_ace_channel_desc_table[channel_handle].signal_id; + ASSERT(channel_id < sizeof(channel_type_lut)); + if(CURRENT_CHANNEL == channel_type_lut[channel_id]) + { + uint32_t resistor; + uint32_t voltage; + + /* Compute index into g_ace_current_resistors[] from the current + * channel number. This uses bit 2, 4 and 5 of the channel number + * to derive the index as follows: + * channel name : channel number : index + * CM0 : 0x03 : 0 + * CM1 : 0x07 : 1 + * CM2 : 0x13 : 2 + * CM3 : 0x17 : 3 + * CM4 : 0x23 : 4 + * CM5 : 0x27 : 5 + */ + current_monitor_idx + = (((uint8_t)channel_id & 0x04u) >> 2u) + (((uint8_t)channel_id & 0x30u) >> 3u); + + if(current_monitor_idx < (uint8_t)ACE_NB_OF_CURRENT_MONITORS) + { + /* Retrieve the current sensing external resistor value from + * the ACE configuration data generated by the ACE configurator. */ + resistor = g_ace_current_resistors[current_monitor_idx]; + + /* Compute mA current value taking into account the amplication + * factor of 50 used within the current monitor hardware. */ + voltage = ACE_convert_adc_input_to_mV(channel_handle, sample_value); + current = (voltage * (1000u / 50u)) / resistor; +; + } + } + } + + return current; +} + +/*-------------------------------------------------------------------------*//** + * + */ +uint32_t ACE_convert_to_Kelvin +( + ace_channel_handle_t channel_handle, + uint16_t sample_value +) +{ + uint32_t temperature; + uint32_t voltage; + + voltage = ACE_convert_adc_input_to_mV( channel_handle, sample_value ); + + /* Tk = (V * 10^3) / 2.5 */ + temperature = (voltage * 10u) / 25u; + + return temperature; +} + +/*-------------------------------------------------------------------------*//** + * + */ +int32_t ACE_convert_to_Celsius +( + ace_channel_handle_t channel_handle, + uint16_t sample_value +) +{ + int32_t temperature; + int32_t voltage; + + voltage = (int32_t)ACE_convert_adc_input_to_mV( channel_handle, sample_value ); + + /* Tk = (V * 10^3) / 2.5 */ + /* Tc = Tk - 273.15 */ + temperature = (voltage * 4) - 2731; + + return temperature; +} + +/*-------------------------------------------------------------------------*//** + * + */ +int32_t ACE_convert_to_Fahrenheit +( + ace_channel_handle_t channel_handle, + uint16_t sample_value +) +{ + int32_t temperature; + + temperature = (int32_t)ACE_convert_to_Kelvin( channel_handle, sample_value ); + + /* F = (K * 9/5) - 459.67 */ + temperature = ((temperature * 9) / 5) - 459; + + return temperature; +} + +/*-------------------------------------------------------------------------*//** + * + */ +const uint8_t * ACE_get_channel_name +( + ace_channel_handle_t channel_handle +) +{ + const uint8_t * p_channel_name = 0; + + if ( channel_handle < NB_OF_ACE_CHANNEL_HANDLES) + { + p_channel_name = g_ace_channel_desc_table[channel_handle].p_sz_channel_name; + } + + return p_channel_name; +} + +/*-------------------------------------------------------------------------*//** + * + */ +uint16_t ACE_convert_mV_to_adc_value +( + ace_channel_handle_t channel_handle, + uint32_t voltage +) +{ + uint16_t sample_value; + adc_channel_id_t channel_id; + uint8_t adc_id; + + channel_id = g_ace_channel_desc_table[channel_handle].signal_id; + adc_id = (uint8_t)channel_id >> 4u; + + if (voltage > g_ace_adc_config[adc_id].va_ref) + { + sample_value = g_ace_adc_config[adc_id].adc_resolution - 1u; + } + else + { + sample_value = (uint16_t)((voltage * (g_ace_adc_config[adc_id].adc_resolution - 1)) / g_ace_adc_config[adc_id].va_ref); + } + + return sample_value; +} + +/*-------------------------------------------------------------------------*//** + * + */ +static uint16_t convert_mV_to_ppe_value +( + ace_channel_handle_t channel_handle, + uint32_t voltage +) +{ + uint16_t sample_value; + adc_channel_id_t channel_id; + uint8_t adc_id; + + channel_id = g_ace_channel_desc_table[channel_handle].signal_id; + adc_id = (uint8_t)channel_id >> 4u; + + if (voltage > g_ace_adc_config[adc_id].va_ref) + { + sample_value = PPE_SAMPLES_RESOLUTION; + } + else + { + sample_value = (uint16_t)((voltage * PPE_SAMPLES_RESOLUTION) / g_ace_adc_config[adc_id].va_ref); + } + + return sample_value; +} + +#define MAX_PPE_SAMPLE_VALUE 0x0FFFu + +/*-------------------------------------------------------------------------*//** + * + */ +uint16_t ACE_convert_from_mV +( + ace_channel_handle_t channel_handle, + int32_t voltage +) +{ + uint16_t sample_value; + adc_channel_id_t channel_id; + uint8_t adc_id; + uint32_t adc_voltage; + + channel_id = g_ace_channel_desc_table[channel_handle].signal_id; + adc_id = (uint8_t)channel_id >> 4u; + + if ( abps_channel_lut[channel_id] == NON_ABPS_CHANNEL ) + { + if (voltage > 0) + { + adc_voltage = (uint32_t)voltage; + } + else + { + adc_voltage = 0u; + } + } + else + { + uint8_t apbs_idx; + uint8_t gdec; + + apbs_idx = abps_idx_lut[channel_id]; + gdec = g_gdec_lut[apbs_idx]; + voltage = voltage + apbs_range[gdec]; + if (voltage > 0) + { + adc_voltage = (uint32_t)voltage; + adc_voltage = adc_voltage / (uint8_t)apbs_gain_lut[gdec]; + } + else + { + adc_voltage = 0; + } + } + + sample_value = (uint16_t)((adc_voltage * PPE_SAMPLES_RESOLUTION) / g_ace_adc_config[adc_id].va_ref); + + if (sample_value > MAX_PPE_SAMPLE_VALUE) + { + sample_value = MAX_PPE_SAMPLE_VALUE; + } + return sample_value; +} + +/*-------------------------------------------------------------------------*//** + * + */ +uint16_t ACE_convert_from_mA +( + ace_channel_handle_t channel_handle, + uint32_t current +) +{ + uint16_t sample_value; + uint32_t voltage; + uint32_t resistor = 1u; + + voltage = current * 50u * resistor; + sample_value = convert_mV_to_ppe_value( channel_handle, voltage ); + + if (sample_value > MAX_PPE_SAMPLE_VALUE) + { + sample_value = MAX_PPE_SAMPLE_VALUE; + } + return sample_value; +} + +/*-------------------------------------------------------------------------*//** + * + */ +uint16_t ACE_convert_from_Kelvin +( + ace_channel_handle_t channel_handle, + uint32_t temperature +) +{ + uint16_t sample_value; + uint32_t voltage; + + voltage = (temperature * 25u) / 10u; + sample_value = convert_mV_to_ppe_value( channel_handle, voltage ); + + if (sample_value > MAX_PPE_SAMPLE_VALUE) + { + sample_value = MAX_PPE_SAMPLE_VALUE; + } + return sample_value; +} + +/*-------------------------------------------------------------------------*//** + * + */ +uint16_t ACE_convert_from_Celsius +( + ace_channel_handle_t channel_handle, + int32_t temperature +) +{ + uint16_t sample_value; + uint32_t voltage; + + temperature = temperature + 2731; + voltage = (uint32_t)temperature / 4u; + sample_value = convert_mV_to_ppe_value( channel_handle, voltage ); + + if (sample_value > MAX_PPE_SAMPLE_VALUE) + { + sample_value = MAX_PPE_SAMPLE_VALUE; + } + return sample_value; +} + +/*-------------------------------------------------------------------------*//** + * + */ +uint16_t ACE_convert_from_Fahrenheit +( + ace_channel_handle_t channel_handle, + int32_t temperature +) +{ + uint16_t sample_value; + uint32_t kelvin; + + temperature = temperature + 459; + kelvin = (uint32_t)temperature; + kelvin = (kelvin * 5u) / 9u; + + sample_value = ACE_convert_from_Kelvin( channel_handle, kelvin ); + + if (sample_value > MAX_PPE_SAMPLE_VALUE) + { + sample_value = MAX_PPE_SAMPLE_VALUE; + } + return sample_value; +} + +/*-------------------------------------------------------------------------*//** + * + */ +uint16_t ACE_translate_pdma_value +( + uint32_t pdma_value, + adc_channel_id_t * channel_id +) +{ + uint16_t ppe_value; + + ppe_value = (pdma_value >> 8u) & 0xFFFFu; + if ( channel_id != 0 ) + { + *channel_id = (adc_channel_id_t)((pdma_value >> 24u) & 0xFFu); + } + + return ppe_value; +} + +#ifdef __cplusplus +} +#endif + diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/ace_flags.c b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/ace_flags.c new file mode 100644 index 000000000..926a80dc2 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/ace_flags.c @@ -0,0 +1,1678 @@ +/******************************************************************************* + * (c) Copyright 2009 Actel Corporation. All rights reserved. + * + * SVN $Revision: 2840 $ + * SVN $Date: 2010-07-20 17:00:32 +0100 (Tue, 20 Jul 2010) $ + */ +#include "mss_ace.h" +#include "mss_ace_configurator.h" +#include "../../CMSIS/a2fxxxm3.h" +#include "../../CMSIS/mss_assert.h" +#include "../../drivers_config/mss_ace/ace_handles.h" +#include "../../drivers_config/mss_ace/ace_config.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAX_FULL_FLAG_NAME_LENGTH (MAX_CHANNEL_NAME_LENGTH + MAX_FLAG_NAME_LENGTH + 1) + +/*-------------------------------------------------------------------------*//** + * Number of flag types supported. + * the supported flag types are: + * - BASIC_THRESHOLD_OVER + * - BASIC_THRESHOLD_UNDER + * - STATE_FILTERED_OVER + * - STATE_FILTERED_UNDER + * - DUAL_HYSTERESIS_OVER + * - DUAL_HYSTERESIS_UNDER + * - IPMI_HYSTERESIS_OVER + * - IPMI_HYSTERESIS_UNDER + */ +#define NB_OF_FLAG_TYPES 8 + +/*-------------------------------------------------------------------------*//** + * + */ +#define THRESHOLD_FLAG0 0u +#define THRESHOLD_FLAG1 1u +#define THRESHOLD_FLAG2 2u +#define THRESHOLD_FLAG3 3u +#define THRESHOLD_FLAG4 4u +#define THRESHOLD_FLAG5 5u +#define THRESHOLD_FLAG6 6u +#define THRESHOLD_FLAG7 7u +#define THRESHOLD_FLAG8 8u +#define THRESHOLD_FLAG9 9u +#define THRESHOLD_FLAG10 10u +#define THRESHOLD_FLAG11 11u +#define THRESHOLD_FLAG12 12u +#define THRESHOLD_FLAG13 13u +#define THRESHOLD_FLAG14 14u +#define THRESHOLD_FLAG15 15u +#define THRESHOLD_FLAG16 16u +#define THRESHOLD_FLAG17 17u +#define THRESHOLD_FLAG18 18u +#define THRESHOLD_FLAG19 19u +#define THRESHOLD_FLAG20 20u +#define THRESHOLD_FLAG21 21u +#define THRESHOLD_FLAG22 22u +#define THRESHOLD_FLAG23 23u +#define THRESHOLD_FLAG24 24u +#define THRESHOLD_FLAG25 25u +#define THRESHOLD_FLAG26 26u +#define THRESHOLD_FLAG27 27u +#define THRESHOLD_FLAG28 28u +#define THRESHOLD_FLAG29 29u +#define THRESHOLD_FLAG30 30u +#define THRESHOLD_FLAG31 31u +#define NB_OF_THRESHOLD_IRQ 32u + +/*-------------------------------------------------------------------------*//** + * + */ +void ace_init_flags( void ); + +/*-------------------------------------------------------------------------*//** + * Flag interrupots routines function prototypes + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag0_IRQHandler( void ); +#else +void ACE_PPE_Flag0_IRQHandler( void ); +#endif + +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag1_IRQHandler( void ); +#else +void ACE_PPE_Flag1_IRQHandler( void ); +#endif + +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag2_IRQHandler( void ); +#else +void ACE_PPE_Flag2_IRQHandler( void ); +#endif + +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag3_IRQHandler( void ); +#else +void ACE_PPE_Flag3_IRQHandler( void ); +#endif + +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag4_IRQHandler( void ); +#else +void ACE_PPE_Flag4_IRQHandler( void ); +#endif + +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag5_IRQHandler( void ); +#else +void ACE_PPE_Flag5_IRQHandler( void ); +#endif + +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag6_IRQHandler( void ); +#else +void ACE_PPE_Flag6_IRQHandler( void ); +#endif + +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag7_IRQHandler( void ); +#else +void ACE_PPE_Flag7_IRQHandler( void ); +#endif + +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag8_IRQHandler( void ); +#else +void ACE_PPE_Flag8_IRQHandler( void ); +#endif + +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag9_IRQHandler( void ); +#else +void ACE_PPE_Flag9_IRQHandler( void ); +#endif + +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag10_IRQHandler( void ); +#else +void ACE_PPE_Flag10_IRQHandler( void ); +#endif + +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag11_IRQHandler( void ); +#else +void ACE_PPE_Flag11_IRQHandler( void ); +#endif + +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag12_IRQHandler( void ); +#else +void ACE_PPE_Flag12_IRQHandler( void ); +#endif + +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag13_IRQHandler( void ); +#else +void ACE_PPE_Flag13_IRQHandler( void ); +#endif + +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag14_IRQHandler( void ); +#else +void ACE_PPE_Flag14_IRQHandler( void ); +#endif + +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag15_IRQHandler( void ); +#else +void ACE_PPE_Flag15_IRQHandler( void ); +#endif + +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag16_IRQHandler( void ); +#else +void ACE_PPE_Flag16_IRQHandler( void ); +#endif + +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag17_IRQHandler( void ); +#else +void ACE_PPE_Flag17_IRQHandler( void ); +#endif + +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag18_IRQHandler( void ); +#else +void ACE_PPE_Flag18_IRQHandler( void ); +#endif + +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag19_IRQHandler( void ); +#else +void ACE_PPE_Flag19_IRQHandler( void ); +#endif + +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag20_IRQHandler( void ); +#else +void ACE_PPE_Flag20_IRQHandler( void ); +#endif + +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag21_IRQHandler( void ); +#else +void ACE_PPE_Flag21_IRQHandler( void ); +#endif + +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag22_IRQHandler( void ); +#else +void ACE_PPE_Flag22_IRQHandler( void ); +#endif + +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag23_IRQHandler( void ); +#else +void ACE_PPE_Flag23_IRQHandler( void ); +#endif + +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag24_IRQHandler( void ); +#else +void ACE_PPE_Flag24_IRQHandler( void ); +#endif + +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag25_IRQHandler( void ); +#else +void ACE_PPE_Flag25_IRQHandler( void ); +#endif + +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag26_IRQHandler( void ); +#else +void ACE_PPE_Flag26_IRQHandler( void ); +#endif + +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag27_IRQHandler( void ); +#else +void ACE_PPE_Flag27_IRQHandler( void ); +#endif + +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag28_IRQHandler( void ); +#else +void ACE_PPE_Flag28_IRQHandler( void ); +#endif + +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag29_IRQHandler( void ); +#else +void ACE_PPE_Flag29_IRQHandler( void ); +#endif + +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag30_IRQHandler( void ); +#else +void ACE_PPE_Flag30_IRQHandler( void ); +#endif + +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag31_IRQHandler( void ); +#else +void ACE_PPE_Flag31_IRQHandler( void ); +#endif + +/*-------------------------------------------------------------------------*//** + * + */ +#if (ACE_NB_OF_PPE_FLAGS > 0) +extern ppe_flag_desc_t g_ppe_flags_desc_table[ACE_NB_OF_PPE_FLAGS]; +#endif + +extern ace_channel_desc_t g_ace_channel_desc_table[ACE_NB_OF_INPUT_CHANNELS]; + +extern ace_adc_config_t g_ace_adc_config[ACE_NB_OF_ADC]; + +#if (ACE_NB_OF_PPE_FLAGS > 0) +/*-------------------------------------------------------------------------*//** + Lookup table indexed on flag_id_t of the index of the flag's descriptor index + in the flag descriptors table g_ppe_flags_desc_table[] + */ +static ace_flag_handle_t g_ppe_flag_handles_lut[NB_OF_PPE_FLAGS]; + +/*-------------------------------------------------------------------------*//** + * + */ +static flag_isr_t g_ppe_flags_isr_lut[NB_OF_PPE_FLAGS]; + +/*-------------------------------------------------------------------------*//** + * + */ +static global_flag_isr_t g_ppe_global_flags_isr; + +/*-------------------------------------------------------------------------*//** + * + */ +static channel_flag_isr_t g_ppe_channel_flags_isr_lut[ACE_NB_OF_INPUT_CHANNELS]; +#endif + +/*-------------------------------------------------------------------------*//** + Intialise the ACE driver's internal data structures used by flag control + functions. + */ +void ace_init_flags( void ) +{ + /* Ensure the generated ACE configuration files are consistent. */ + ASSERT(NB_OF_ACE_FLAG_HANDLES == ACE_NB_OF_PPE_FLAGS); + +#if (ACE_NB_OF_PPE_FLAGS > 0) + { + uint8_t flag_idx; + uint8_t channel_idx; + + for ( flag_idx = 0u; flag_idx < (uint8_t)NB_OF_PPE_FLAGS; ++flag_idx ) + { + g_ppe_flags_isr_lut[flag_idx] = 0; + g_ppe_flag_handles_lut[flag_idx] = INVALID_FLAG_HANDLE; + } + + for ( flag_idx = 0u; flag_idx < (uint8_t)ACE_NB_OF_PPE_FLAGS; ++flag_idx ) + { + ASSERT( g_ppe_flags_desc_table[flag_idx].flag_id < NB_OF_PPE_FLAGS ); + g_ppe_flag_handles_lut[g_ppe_flags_desc_table[flag_idx].flag_id] = (ace_flag_handle_t)flag_idx; + } + + for ( channel_idx = 0u; channel_idx < (uint8_t)ACE_NB_OF_INPUT_CHANNELS; ++channel_idx ) + { + g_ppe_channel_flags_isr_lut[channel_idx] = 0; + } + + g_ppe_global_flags_isr = 0u; + } +#endif +} + +/*-------------------------------------------------------------------------*//** + * + */ +uint32_t ACE_is_hysteresis_flag( ace_flag_handle_t flag_handle ) +{ + uint32_t hysteresis = 0u; + +#if (ACE_NB_OF_PPE_FLAGS > 0) + ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES ); + + if ( g_ppe_flags_desc_table[flag_handle].flag_type >= DUAL_HYSTERESIS_OVER ) + { + hysteresis = 1u; + } +#endif + return hysteresis; +} + +/*-------------------------------------------------------------------------*//** + * + */ +uint32_t ACE_is_under_flag +( + ace_flag_handle_t flag_handle +) +{ + uint32_t is_under = 0; + +#if (ACE_NB_OF_PPE_FLAGS > 0) + const uint32_t flag_type_lut[NB_OF_FLAG_TYPES] = + { + 0, /* BASIC_THRESHOLD_OVER */ + 1, /* BASIC_THRESHOLD_UNDER */ + 0, /* STATE_FILTERED_OVER */ + 1, /* STATE_FILTERED_UNDER */ + 0, /* DUAL_HYSTERESIS_OVER */ + 1, /* DUAL_HYSTERESIS_UNDER */ + 0, /* IPMI_HYSTERESIS_OVER */ + 1, /* IPMI_HYSTERESIS_UNDER */ + }; + + ASSERT(flag_handle < ACE_NB_OF_PPE_FLAGS); + if (flag_handle < ACE_NB_OF_PPE_FLAGS) + { + uint8_t flag_type; + flag_type = g_ppe_flags_desc_table[flag_handle].flag_type; + ASSERT(flag_type < NB_OF_FLAG_TYPES); + if (flag_type < NB_OF_FLAG_TYPES) + { + is_under = flag_type_lut[flag_type]; + } + } +#endif + return is_under; +} + +/*-------------------------------------------------------------------------*//** + Mask of the threshold value bits within a PPE RAM meory location holding the + threshold value for a flag. + */ +#define PPE_RAM_THRESHOLD_MASK 0x0000FFFFuL + +/*-------------------------------------------------------------------------*//** + * TODO: handle IPMI hysteresis flags + */ +void ACE_set_flag_threshold +( + ace_flag_handle_t flag_handle, + uint16_t new_threshold +) +{ +#if (ACE_NB_OF_PPE_FLAGS > 0) + uint16_t ppe_offset; + + ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES ); + + if ( flag_handle < NB_OF_ACE_FLAG_HANDLES ) + { + + ppe_offset = g_ppe_flags_desc_table[flag_handle].threshold_ppe_offset; + + if ( ACE_is_hysteresis_flag( flag_handle ) == 0u ) + { + ACE->PPE_RAM_DATA[ppe_offset] = (ACE->PPE_RAM_DATA[ppe_offset] & (uint32_t)~PPE_RAM_THRESHOLD_MASK) + new_threshold; + } + else + { + uint16_t high_threshold; + uint16_t low_threshold; + ace_channel_handle_t channel_handle; + uint16_t hysteresis; + uint32_t adc_id; + uint16_t adc_resolution; + + high_threshold = (uint16_t)(ACE->PPE_RAM_DATA[ppe_offset] & PPE_RAM_THRESHOLD_MASK); + low_threshold = (uint16_t)(ACE->PPE_RAM_DATA[ppe_offset + 1u] & PPE_RAM_THRESHOLD_MASK); + ASSERT(high_threshold > low_threshold); + hysteresis = (uint16_t)(high_threshold - low_threshold) / 2u; + + channel_handle = g_ppe_flags_desc_table[flag_handle].channel_handle; + adc_id = (uint32_t)(g_ace_channel_desc_table[channel_handle].signal_id) >> 4u; + ASSERT( adc_id < (uint32_t)ACE_NB_OF_ADC ); + + if ( adc_id < (uint32_t)ACE_NB_OF_ADC ) + { + adc_resolution = g_ace_adc_config[adc_id].adc_resolution - 1u; + + high_threshold = new_threshold + hysteresis; + if ( high_threshold > adc_resolution ) + { + high_threshold = adc_resolution; + } + + if ( hysteresis > new_threshold ) + { + low_threshold = 1u; + } + else + { + low_threshold = new_threshold - hysteresis; + } + + ACE->PPE_RAM_DATA[ppe_offset] = (ACE->PPE_RAM_DATA[ppe_offset] & ~PPE_RAM_THRESHOLD_MASK) + high_threshold; + ACE->PPE_RAM_DATA[ppe_offset + 1u] = (ACE->PPE_RAM_DATA[ppe_offset + 1u] & (uint32_t)~PPE_RAM_THRESHOLD_MASK) + low_threshold; + } + } + } +#endif +} + + +/*-------------------------------------------------------------------------*//** + * + */ +#define FLAG_OVER_UNDER_MASK 0x01u +#define FLAG_OVER 0x00u +#define FLAF_UNDER 0x01 + +void ACE_set_flag_assertion +( + ace_flag_handle_t flag_handle, + uint16_t assertion_value +) +{ +#if (ACE_NB_OF_PPE_FLAGS > 0) + uint16_t ppe_offset; + + ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES ); + + if ( flag_handle < NB_OF_ACE_FLAG_HANDLES ) + { + if (ACE_is_hysteresis_flag(flag_handle)) + { + uint8_t flag_direction; + flag_direction = g_ppe_flags_desc_table[flag_handle].flag_type & FLAG_OVER_UNDER_MASK; + + if ( FLAG_OVER == flag_direction ) + { + ppe_offset = g_ppe_flags_desc_table[flag_handle].threshold_ppe_offset; + } + else + { + ppe_offset = g_ppe_flags_desc_table[flag_handle].threshold_ppe_offset + 1u; + } + } + else + { + ppe_offset = g_ppe_flags_desc_table[flag_handle].threshold_ppe_offset; + } + ACE->PPE_RAM_DATA[ppe_offset] = (ACE->PPE_RAM_DATA[ppe_offset] & ~PPE_RAM_THRESHOLD_MASK) + assertion_value; + } +#endif +} + +/*-------------------------------------------------------------------------*//** + * + */ +void ACE_set_flag_deassertion +( + ace_flag_handle_t flag_handle, + uint16_t assertion_value +) +{ +#if (ACE_NB_OF_PPE_FLAGS > 0) + uint16_t ppe_offset; + + ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES ); + ASSERT(ACE_is_hysteresis_flag(flag_handle)); + + if ((flag_handle < NB_OF_ACE_FLAG_HANDLES) && (ACE_is_hysteresis_flag(flag_handle))) + { + uint8_t flag_direction; + flag_direction = g_ppe_flags_desc_table[flag_handle].flag_type & FLAG_OVER_UNDER_MASK; + + if ( FLAG_OVER == flag_direction ) + { + ppe_offset = g_ppe_flags_desc_table[flag_handle].threshold_ppe_offset + 1u; + } + else + { + ppe_offset = g_ppe_flags_desc_table[flag_handle].threshold_ppe_offset; + } + + ACE->PPE_RAM_DATA[ppe_offset] = (ACE->PPE_RAM_DATA[ppe_offset] & ~PPE_RAM_THRESHOLD_MASK) + assertion_value; + } +#endif +} + +/*-------------------------------------------------------------------------*//** + * + */ +void +ACE_set_flag_hysteresis +( + ace_flag_handle_t flag_handle, + uint16_t adc_hysteresis +) +{ +#if (ACE_NB_OF_PPE_FLAGS > 0) + uint16_t ppe_offset; + uint32_t high_threshold; + uint32_t low_threshold; + uint32_t nominal_threshold; + uint16_t adc_resolution; + uint32_t adc_id; + + ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES ); + ASSERT(ACE_is_hysteresis_flag(flag_handle)); + + if ( ( flag_handle < NB_OF_ACE_FLAG_HANDLES ) && ( ACE_is_hysteresis_flag( flag_handle ) ) ) + { + ace_channel_handle_t channel_handle; + + ppe_offset = g_ppe_flags_desc_table[flag_handle].threshold_ppe_offset; + + high_threshold = ACE->PPE_RAM_DATA[ppe_offset] & PPE_RAM_THRESHOLD_MASK; + low_threshold = ACE->PPE_RAM_DATA[ppe_offset + 1u] & PPE_RAM_THRESHOLD_MASK; + ASSERT(high_threshold > low_threshold); + nominal_threshold = (low_threshold + ((high_threshold - low_threshold) / 2u)); + + channel_handle = g_ppe_flags_desc_table[flag_handle].channel_handle; + adc_id = (uint32_t)((uint32_t)g_ace_channel_desc_table[channel_handle].signal_id >> 4u); + ASSERT( adc_id < (uint32_t)ACE_NB_OF_ADC ); + + if ( adc_id < (uint32_t)ACE_NB_OF_ADC ) + { + adc_resolution = g_ace_adc_config[adc_id].adc_resolution; + + high_threshold = nominal_threshold + adc_hysteresis; + if ( high_threshold > adc_resolution ) + { + high_threshold = (uint32_t)adc_resolution - 1u; + } + + if ( adc_hysteresis > nominal_threshold ) + { + low_threshold = 1u; + } + else + { + low_threshold = nominal_threshold - adc_hysteresis; + } + + ACE->PPE_RAM_DATA[ppe_offset] = (ACE->PPE_RAM_DATA[ppe_offset] & ~PPE_RAM_THRESHOLD_MASK) + high_threshold; + ACE->PPE_RAM_DATA[ppe_offset + 1u] = (ACE->PPE_RAM_DATA[ppe_offset + 1u] & ~PPE_RAM_THRESHOLD_MASK) + low_threshold; + } + } +#endif +} + + +/*-------------------------------------------------------------------------*//** + * + */ +void +ACE_set_channel_hysteresis +( + ace_channel_handle_t channel_handle, + uint16_t adc_hysteresis +) +{ +#if (ACE_NB_OF_PPE_FLAGS > 0) + ace_flag_handle_t flag_handle; + + ASSERT( channel_handle < NB_OF_ACE_CHANNEL_HANDLES ); + + if ( channel_handle < NB_OF_ACE_CHANNEL_HANDLES ) + { + uint16_t i; + + for( i = 0u; i < g_ace_channel_desc_table[channel_handle].nb_of_flags; ++i ) + { + flag_handle = (ace_flag_handle_t)g_ace_channel_desc_table[channel_handle].p_flags_array[i]; + ACE_set_flag_hysteresis( flag_handle, adc_hysteresis ); + } + } +#endif +} + +/*============================================================================== + * + */ + +/*-------------------------------------------------------------------------*//** + Masking a flag_id with FLAG_BIT_OFFSET_MASK results in the offset of the + flag bit within a PPE__FLAGSn register. + */ +#define FLAG_BIT_OFFSET_MASK 0x0000001FuL + +/*-------------------------------------------------------------------------*//** + Shifting right a flag_id by FLAG_PPE_REG_SHIFT results in identifying the + PPE_FLAGSn or PPE_SFFLAGS the flags belongs to. + */ +#define FLAG_PPE_REG_SHIFT 5u + +/*-------------------------------------------------------------------------*//** + There is a set of 5 PPE flag registers to control and report status of the PPE + flags resulting in the PPE flags being grouped into 5 separate flag groups at + the register level. Each register provides status or control for 32 flags. + */ +#define NB_OF_FLAG_GROUPS 5u +#define NB_OF_FLAGS_PER_GROUP 32u + +#if (ACE_NB_OF_PPE_FLAGS > 0) +/*-------------------------------------------------------------------------*//** + Lookup table of the address PPE_FLAGSn registers for fast reading of PPE + status. + */ +static volatile uint32_t * const g_ppe_flags_regs_lut[NB_OF_FLAG_GROUPS] = +{ + &ACE->PPE_FLAGS0, + &ACE->PPE_FLAGS1, + &ACE->PPE_FLAGS2, + &ACE->PPE_FLAGS3, + &ACE->PPE_SFFLAGS +}; + +/*-------------------------------------------------------------------------*//** + Lookup table of the address of the PPE flags interrupt enable registers. + */ +static uint32_t volatile * const flags_irq_enable_regs_lut[NB_OF_FLAG_GROUPS] = +{ + &ACE->PPE_FLAGS0_IRQ_EN, + &ACE->PPE_FLAGS1_IRQ_EN, + &ACE->PPE_FLAGS2_IRQ_EN, + &ACE->PPE_FLAGS3_IRQ_EN, + &ACE->PPE_SFFLAGS_IRQ_EN +}; + +/*-------------------------------------------------------------------------*//** + Lookup table of the address of the PPE flags interrupt status registers. + */ +static uint32_t volatile const * const flags_irq_status_regs_lut[NB_OF_FLAG_GROUPS] = +{ + &ACE->PPE_FLAGS0_IRQ, + &ACE->PPE_FLAGS1_IRQ, + &ACE->PPE_FLAGS2_IRQ, + &ACE->PPE_FLAGS3_IRQ, + &ACE->PPE_SFFLAGS_IRQ +}; + +/*-------------------------------------------------------------------------*//** + Lookup table of the address of the PPE flags interrupt clearing registers. + */ +static uint32_t volatile * const flags_irq_clear_regs_lut[NB_OF_FLAG_GROUPS] = +{ + &ACE->PPE_FLAGS0_IRQ_CLR, + &ACE->PPE_FLAGS1_IRQ_CLR, + &ACE->PPE_FLAGS2_IRQ_CLR, + &ACE->PPE_FLAGS3_IRQ_CLR, + &ACE->PPE_SFFLAGS_IRQ_CLR +}; + +/*-------------------------------------------------------------------------*//** + * + */ +static const IRQn_Type threshold_irqn_lut[NB_OF_THRESHOLD_IRQ] = +{ + ACE_PPE_Flag0_IRQn, + ACE_PPE_Flag1_IRQn, + ACE_PPE_Flag2_IRQn, + ACE_PPE_Flag3_IRQn, + ACE_PPE_Flag4_IRQn, + ACE_PPE_Flag5_IRQn, + ACE_PPE_Flag6_IRQn, + ACE_PPE_Flag7_IRQn, + ACE_PPE_Flag8_IRQn, + ACE_PPE_Flag9_IRQn, + ACE_PPE_Flag10_IRQn, + ACE_PPE_Flag11_IRQn, + ACE_PPE_Flag12_IRQn, + ACE_PPE_Flag13_IRQn, + ACE_PPE_Flag14_IRQn, + ACE_PPE_Flag15_IRQn, + ACE_PPE_Flag16_IRQn, + ACE_PPE_Flag17_IRQn, + ACE_PPE_Flag18_IRQn, + ACE_PPE_Flag19_IRQn, + ACE_PPE_Flag20_IRQn, + ACE_PPE_Flag21_IRQn, + ACE_PPE_Flag22_IRQn, + ACE_PPE_Flag23_IRQn, + ACE_PPE_Flag24_IRQn, + ACE_PPE_Flag25_IRQn, + ACE_PPE_Flag26_IRQn, + ACE_PPE_Flag27_IRQn, + ACE_PPE_Flag28_IRQn, + ACE_PPE_Flag29_IRQn, + ACE_PPE_Flag30_IRQn, + ACE_PPE_Flag31_IRQn +}; +#endif + +/*-------------------------------------------------------------------------*//** + */ +ace_flag_handle_t +ACE_get_flag_handle +( + const uint8_t * p_sz_full_flag_name +) +{ + ace_flag_handle_t flag_handle = INVALID_FLAG_HANDLE; +#if (ACE_NB_OF_PPE_FLAGS > 0) + ace_flag_handle_t flag_idx; + + for ( flag_idx = (ace_flag_handle_t)0; flag_idx < NB_OF_ACE_FLAG_HANDLES; ++flag_idx ) + { + if ( g_ppe_flags_desc_table[flag_idx].p_sz_flag_name != 0 ) + { + int32_t diff; + diff = strncmp( (const char *)p_sz_full_flag_name, (const char *)g_ppe_flags_desc_table[flag_idx].p_sz_flag_name, (size_t)MAX_FULL_FLAG_NAME_LENGTH ); + if ( 0 == diff ) + { + /* flag name found. */ + flag_handle = (ace_flag_handle_t)flag_idx; + break; + } + } + } +#endif + return flag_handle; +} + +/*-------------------------------------------------------------------------*//** + */ +int32_t +ACE_get_flag_status +( + ace_flag_handle_t flag_handle +) +{ + int32_t flag_state = UNKNOWN_FLAG; +#if (ACE_NB_OF_PPE_FLAGS > 0) + ppe_flag_id_t flag_id; + + ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES ); + + if ( flag_handle < NB_OF_ACE_FLAG_HANDLES ) + { + uint32_t flag_bit_offset; + uint32_t ppe_flag_group; + uint32_t flag_id_mask; + uint32_t flag_status; + + flag_id = g_ppe_flags_desc_table[flag_handle].flag_id; + + if ( flag_id < NB_OF_PPE_FLAGS ) + { + flag_bit_offset = ((uint32_t)flag_id & FLAG_BIT_OFFSET_MASK); + ppe_flag_group = ((uint32_t)flag_id >> FLAG_PPE_REG_SHIFT); + flag_id_mask = 1uL << flag_bit_offset; + flag_status = *(g_ppe_flags_regs_lut[ppe_flag_group]) & flag_id_mask; + if ( flag_status > 0u ) + { + flag_state = FLAG_ASSERTED; + } + else + { + flag_state = FLAG_NOT_ASSERTED; + } + } + + } +#endif + return flag_state; +} + + +/*-------------------------------------------------------------------------*//** + */ +const uint8_t * +ACE_get_flag_name +( + ace_flag_handle_t flag_handle +) +{ + const uint8_t * psz_flag_name = 0; +#if (ACE_NB_OF_PPE_FLAGS > 0) + ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES ); + + if ( flag_handle < NB_OF_ACE_FLAG_HANDLES ) + { + psz_flag_name = g_ppe_flags_desc_table[flag_handle].p_sz_flag_name; + } +#endif + return psz_flag_name; +} + +/*-------------------------------------------------------------------------*//** + */ +ace_channel_handle_t +ACE_get_flag_channel +( + ace_flag_handle_t flag_handle +) +{ + ace_channel_handle_t channel_handle = INVALID_CHANNEL_HANDLE; +#if (ACE_NB_OF_PPE_FLAGS > 0) + ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES ); + + if ( flag_handle < NB_OF_ACE_FLAG_HANDLES ) + { + channel_handle = g_ppe_flags_desc_table[flag_handle].channel_handle; + } +#endif + return channel_handle; +} + +/*-------------------------------------------------------------------------*//** + */ +uint32_t +ACE_get_channel_flag_count +( + ace_channel_handle_t channel_handle +) +{ + uint32_t flag_count = 0; +#if (ACE_NB_OF_PPE_FLAGS > 0) + ASSERT( channel_handle < ACE_NB_OF_INPUT_CHANNELS ); + if (channel_handle < ACE_NB_OF_INPUT_CHANNELS) + { + flag_count = g_ace_channel_desc_table[channel_handle].nb_of_flags; + } +#endif + return flag_count; +} + +/*-------------------------------------------------------------------------*//** + + */ +ace_flag_handle_t +ACE_get_channel_first_flag +( + ace_channel_handle_t channel_handle, + uint16_t * iterator +) +{ + ace_flag_handle_t flag_handle = INVALID_FLAG_HANDLE; +#if (ACE_NB_OF_PPE_FLAGS > 0) + ASSERT( channel_handle < NB_OF_ACE_CHANNEL_HANDLES); + + *iterator = 0u; + + if ( channel_handle < NB_OF_ACE_CHANNEL_HANDLES) + { + if ( g_ace_channel_desc_table[channel_handle].nb_of_flags > 0u ) + { + flag_handle = (ace_flag_handle_t)g_ace_channel_desc_table[channel_handle].p_flags_array[*iterator]; + } + } +#endif + return flag_handle; +} + +/*-------------------------------------------------------------------------*//** + + */ +ace_flag_handle_t +ACE_get_channel_next_flag +( + ace_channel_handle_t channel_handle, + uint16_t * iterator +) +{ + ace_flag_handle_t flag_handle = INVALID_FLAG_HANDLE; +#if (ACE_NB_OF_PPE_FLAGS > 0) + ASSERT( channel_handle < NB_OF_ACE_CHANNEL_HANDLES); + + if ( channel_handle < NB_OF_ACE_CHANNEL_HANDLES) + { + ++(*iterator); + + if ( *iterator >= g_ace_channel_desc_table[channel_handle].nb_of_flags ) + { + *iterator = 0u; + } + + if ( g_ace_channel_desc_table[channel_handle].nb_of_flags > 0u ) + { + flag_handle = (ace_flag_handle_t)g_ace_channel_desc_table[channel_handle].p_flags_array[*iterator]; + } + } +#endif + return flag_handle; +} + + +/*-------------------------------------------------------------------------*//** + * + */ +void ACE_enable_channel_flags_irq +( + ace_channel_handle_t channel_handle +) +{ +#if (ACE_NB_OF_PPE_FLAGS > 0) + uint32_t flag_idx; + ace_flag_handle_t flag_handle; + + ASSERT( channel_handle < NB_OF_ACE_CHANNEL_HANDLES ); + + if ( channel_handle < NB_OF_ACE_CHANNEL_HANDLES ) + { + for ( flag_idx = 0u; flag_idx < g_ace_channel_desc_table[channel_handle].nb_of_flags; ++flag_idx ) + { + flag_handle = (ace_flag_handle_t)g_ace_channel_desc_table[channel_handle].p_flags_array[flag_idx]; + ACE_enable_flag_irq( flag_handle ); + } + } +#endif +} + +/*-------------------------------------------------------------------------*//** + * + */ +void ACE_disable_channel_flags_irq +( + ace_channel_handle_t channel_handle +) +{ +#if (ACE_NB_OF_PPE_FLAGS > 0) + uint32_t flag_idx; + ace_flag_handle_t flag_handle; + + ASSERT( channel_handle < NB_OF_ACE_CHANNEL_HANDLES ); + + if ( channel_handle < NB_OF_ACE_CHANNEL_HANDLES ) + { + for ( flag_idx = 0u; flag_idx < g_ace_channel_desc_table[channel_handle].nb_of_flags; ++flag_idx ) + { + flag_handle = (ace_flag_handle_t)g_ace_channel_desc_table[channel_handle].p_flags_array[flag_idx]; + ACE_disable_flag_irq( flag_handle ); + } + } +#endif +} + +/*-------------------------------------------------------------------------*//** + * + */ +void ACE_clear_channel_flags_irq +( + ace_channel_handle_t channel_handle +) +{ +#if (ACE_NB_OF_PPE_FLAGS > 0) + uint32_t flag_idx; + ace_flag_handle_t flag_handle; + + ASSERT( channel_handle < NB_OF_ACE_CHANNEL_HANDLES ); + + if ( channel_handle < NB_OF_ACE_CHANNEL_HANDLES ) + { + for ( flag_idx = 0u; flag_idx < g_ace_channel_desc_table[channel_handle].nb_of_flags; ++flag_idx ) + { + flag_handle = (ace_flag_handle_t)g_ace_channel_desc_table[channel_handle].p_flags_array[flag_idx]; + ACE_clear_flag_irq( flag_handle ); + } + } +#endif +} + +/*-------------------------------------------------------------------------*//** + * + */ +void ACE_enable_flag_irq +( + ace_flag_handle_t flag_handle +) +{ +#if (ACE_NB_OF_PPE_FLAGS > 0) + ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES ); + + if ( flag_handle < NB_OF_ACE_FLAG_HANDLES ) + { + ppe_flag_id_t flag_id; + uint32_t flag_bit_offset; + uint32_t ppe_flag_group; + uint32_t flag_id_mask; + + flag_id = g_ppe_flags_desc_table[flag_handle].flag_id; + + ASSERT( flag_id < NB_OF_PPE_FLAGS ); + + flag_bit_offset = ((uint32_t)flag_id & FLAG_BIT_OFFSET_MASK); + ppe_flag_group = ((uint32_t)flag_id >> FLAG_PPE_REG_SHIFT); + flag_id_mask = 1uL << flag_bit_offset; + + ASSERT( ppe_flag_group < NB_OF_FLAG_GROUPS ); + + if ( ppe_flag_group < NB_OF_FLAG_GROUPS ) + { + *(flags_irq_enable_regs_lut[ppe_flag_group]) |= flag_id_mask; + } + + NVIC_EnableIRQ( threshold_irqn_lut[flag_bit_offset] ); + } +#endif +} + +/*-------------------------------------------------------------------------*//** + * + */ +void ACE_disable_flag_irq +( + ace_flag_handle_t flag_handle +) +{ +#if (ACE_NB_OF_PPE_FLAGS > 0) + ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES ); + + if ( flag_handle < NB_OF_ACE_FLAG_HANDLES ) + { + ppe_flag_id_t flag_id; + uint32_t flag_bit_offset; + uint32_t ppe_flag_group; + uint32_t flag_id_mask; + + flag_id = g_ppe_flags_desc_table[flag_handle].flag_id; + + ASSERT( flag_id < NB_OF_PPE_FLAGS ); + + flag_bit_offset = ((uint32_t)flag_id & FLAG_BIT_OFFSET_MASK); + ppe_flag_group = ((uint32_t)flag_id >> FLAG_PPE_REG_SHIFT); + flag_id_mask = 1uL << flag_bit_offset; + + ASSERT( ppe_flag_group < NB_OF_FLAG_GROUPS ); + + if ( ppe_flag_group < NB_OF_FLAG_GROUPS ) + { + *(flags_irq_enable_regs_lut[ppe_flag_group]) &= (uint32_t)~flag_id_mask; + } + } +#endif +} + +/*-------------------------------------------------------------------------*//** + * + */ +void ACE_clear_flag_irq +( + ace_flag_handle_t flag_handle +) +{ +#if (ACE_NB_OF_PPE_FLAGS > 0) + ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES ); + + if ( flag_handle < NB_OF_ACE_FLAG_HANDLES ) + { + ppe_flag_id_t flag_id; + uint32_t flag_bit_offset; + uint32_t ppe_flag_group; + uint32_t flag_id_mask; + + flag_id = g_ppe_flags_desc_table[flag_handle].flag_id; + + ASSERT( flag_id < NB_OF_PPE_FLAGS ); + + flag_bit_offset = ((uint32_t)flag_id & FLAG_BIT_OFFSET_MASK); + ppe_flag_group = ((uint32_t)flag_id >> FLAG_PPE_REG_SHIFT); + flag_id_mask = 1uL << flag_bit_offset; + + ASSERT( ppe_flag_group < NB_OF_FLAG_GROUPS ); + + if ( ppe_flag_group < NB_OF_FLAG_GROUPS ) + { + *(flags_irq_clear_regs_lut[ppe_flag_group]) |= flag_id_mask; + } + } +#endif +} + +/*-------------------------------------------------------------------------*//** + * + */ +void ACE_register_flag_isr +( + ace_flag_handle_t flag_handle, + flag_isr_t flag_isr +) +{ +#if (ACE_NB_OF_PPE_FLAGS > 0) + ppe_flag_id_t flag_id; + + ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES ); + + if ( flag_handle < NB_OF_ACE_FLAG_HANDLES ) + { + flag_id = g_ppe_flags_desc_table[flag_handle].flag_id; + + ASSERT( flag_id < NB_OF_PPE_FLAGS ); + + if ( flag_id < NB_OF_PPE_FLAGS ) + { + g_ppe_flags_isr_lut[flag_id] = flag_isr; + } + } +#endif +} + +/*-------------------------------------------------------------------------*//** + * + */ +void ACE_register_channel_flags_isr +( + ace_channel_handle_t channel_handle, + channel_flag_isr_t channel_flag_isr +) +{ +#if (ACE_NB_OF_PPE_FLAGS > 0) + ASSERT( channel_handle < NB_OF_ACE_CHANNEL_HANDLES ); + + if ( channel_handle < NB_OF_ACE_CHANNEL_HANDLES ) + { + g_ppe_channel_flags_isr_lut[channel_handle] = channel_flag_isr; + } +#endif +} + +/*-------------------------------------------------------------------------*//** + * + */ +void ACE_register_global_flags_isr +( + global_flag_isr_t global_flag_isr +) +{ +#if (ACE_NB_OF_PPE_FLAGS > 0) + g_ppe_global_flags_isr = global_flag_isr; +#endif +} + + +/*============================================================================== + * + */ + +/*-------------------------------------------------------------------------*//** + * Actual PPE flag interrupt service routines: + */ + +static void process_flag_irq( uint8_t threshold_flag_id ) +{ +#if (ACE_NB_OF_PPE_FLAGS > 0) + uint8_t flag_group; + uint32_t threshold_flag_mask; + ppe_flag_id_t flag_id; + uint32_t irq_enable_reg; + uint32_t irq_status_reg; + uint32_t irq_active; + + threshold_flag_mask = 1uL << threshold_flag_id; + + + for ( flag_group = 0u; flag_group < NB_OF_FLAG_GROUPS; ++flag_group ) + { + irq_enable_reg = *flags_irq_enable_regs_lut[flag_group]; + irq_status_reg = *flags_irq_status_regs_lut[flag_group]; + irq_active = threshold_flag_mask & irq_enable_reg & irq_status_reg; + + if ( irq_active ) + { + ace_flag_handle_t flag_handle; + ace_channel_handle_t channel_handle; + + flag_id = (ppe_flag_id_t)((flag_group * NB_OF_FLAGS_PER_GROUP) + threshold_flag_id); + flag_handle = g_ppe_flag_handles_lut[flag_id]; + + /* Call individual flag handler */ + if ( g_ppe_flags_isr_lut[flag_id] != 0 ) + { + g_ppe_flags_isr_lut[flag_id]( flag_handle ); + } + + /* Call the channel flag handler. */ + channel_handle = g_ppe_flags_desc_table[flag_handle].channel_handle; + if ( channel_handle < NB_OF_ACE_CHANNEL_HANDLES ) + { + if ( g_ppe_channel_flags_isr_lut[channel_handle] != 0 ) + { + g_ppe_channel_flags_isr_lut[channel_handle]( flag_handle ); + } + } + + /* Call the global flag handler. */ + if ( g_ppe_global_flags_isr != 0 ) + { + g_ppe_global_flags_isr( flag_handle, channel_handle ); + } + + /* Clear the flag interrupt */ + *flags_irq_clear_regs_lut[flag_group] |= threshold_flag_mask; + } + } +#endif +} + +/*-------------------------------------------------------------------------*//** + * + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag0_IRQHandler( void ) +#else +void ACE_PPE_Flag0_IRQHandler( void ) +#endif +{ + process_flag_irq( THRESHOLD_FLAG0 ); + NVIC_ClearPendingIRQ( ACE_PPE_Flag0_IRQn ); +} + +/*-------------------------------------------------------------------------*//** + * + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag1_IRQHandler( void ) +#else +void ACE_PPE_Flag1_IRQHandler( void ) +#endif +{ + process_flag_irq( THRESHOLD_FLAG1 ); + NVIC_ClearPendingIRQ( ACE_PPE_Flag1_IRQn ); +} + +/*-------------------------------------------------------------------------*//** + * + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag2_IRQHandler( void ) +#else +void ACE_PPE_Flag2_IRQHandler( void ) +#endif +{ + process_flag_irq( THRESHOLD_FLAG2 ); + NVIC_ClearPendingIRQ( ACE_PPE_Flag2_IRQn ); +} + +/*-------------------------------------------------------------------------*//** + * + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag3_IRQHandler( void ) +#else +void ACE_PPE_Flag3_IRQHandler( void ) +#endif +{ + process_flag_irq( THRESHOLD_FLAG3 ); + NVIC_ClearPendingIRQ( ACE_PPE_Flag3_IRQn ); +} + +/*-------------------------------------------------------------------------*//** + * + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag4_IRQHandler( void ) +#else +void ACE_PPE_Flag4_IRQHandler( void ) +#endif +{ + process_flag_irq( THRESHOLD_FLAG4 ); + NVIC_ClearPendingIRQ( ACE_PPE_Flag4_IRQn ); +} + +/*-------------------------------------------------------------------------*//** + * + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag5_IRQHandler( void ) +#else +void ACE_PPE_Flag5_IRQHandler( void ) +#endif +{ + process_flag_irq( THRESHOLD_FLAG5 ); + NVIC_ClearPendingIRQ( ACE_PPE_Flag5_IRQn ); +} + +/*-------------------------------------------------------------------------*//** + * + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag6_IRQHandler( void ) +#else +void ACE_PPE_Flag6_IRQHandler( void ) +#endif +{ + process_flag_irq( THRESHOLD_FLAG6 ); + NVIC_ClearPendingIRQ( ACE_PPE_Flag6_IRQn ); +} + +/*-------------------------------------------------------------------------*//** + * + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag7_IRQHandler( void ) +#else +void ACE_PPE_Flag7_IRQHandler( void ) +#endif +{ + process_flag_irq( THRESHOLD_FLAG7 ); + NVIC_ClearPendingIRQ( ACE_PPE_Flag7_IRQn ); +} + +/*-------------------------------------------------------------------------*//** + * + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag8_IRQHandler( void ) +#else +void ACE_PPE_Flag8_IRQHandler( void ) +#endif +{ + process_flag_irq( THRESHOLD_FLAG8 ); + NVIC_ClearPendingIRQ( ACE_PPE_Flag8_IRQn ); +} + +/*-------------------------------------------------------------------------*//** + * + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag9_IRQHandler( void ) +#else +void ACE_PPE_Flag9_IRQHandler( void ) +#endif +{ + process_flag_irq( THRESHOLD_FLAG9 ); + NVIC_ClearPendingIRQ( ACE_PPE_Flag9_IRQn ); +} + +/*-------------------------------------------------------------------------*//** + * + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag10_IRQHandler( void ) +#else +void ACE_PPE_Flag10_IRQHandler( void ) +#endif +{ + process_flag_irq( THRESHOLD_FLAG10 ); + NVIC_ClearPendingIRQ( ACE_PPE_Flag10_IRQn ); +} + +/*-------------------------------------------------------------------------*//** + * + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag11_IRQHandler( void ) +#else +void ACE_PPE_Flag11_IRQHandler( void ) +#endif +{ + process_flag_irq( THRESHOLD_FLAG11 ); + NVIC_ClearPendingIRQ( ACE_PPE_Flag11_IRQn ); +} + +/*-------------------------------------------------------------------------*//** + * + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag12_IRQHandler( void ) +#else +void ACE_PPE_Flag12_IRQHandler( void ) +#endif +{ + process_flag_irq( THRESHOLD_FLAG12 ); + NVIC_ClearPendingIRQ( ACE_PPE_Flag12_IRQn ); +} + +/*-------------------------------------------------------------------------*//** + * + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag13_IRQHandler( void ) +#else +void ACE_PPE_Flag13_IRQHandler( void ) +#endif +{ + process_flag_irq( THRESHOLD_FLAG13 ); + NVIC_ClearPendingIRQ( ACE_PPE_Flag13_IRQn ); +} + +/*-------------------------------------------------------------------------*//** + * + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag14_IRQHandler( void ) +#else +void ACE_PPE_Flag14_IRQHandler( void ) +#endif +{ + process_flag_irq( THRESHOLD_FLAG14 ); + NVIC_ClearPendingIRQ( ACE_PPE_Flag14_IRQn ); +} + +/*-------------------------------------------------------------------------*//** + * + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag15_IRQHandler( void ) +#else +void ACE_PPE_Flag15_IRQHandler( void ) +#endif +{ + process_flag_irq( THRESHOLD_FLAG15 ); + NVIC_ClearPendingIRQ( ACE_PPE_Flag15_IRQn ); +} + +/*-------------------------------------------------------------------------*//** + * + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag16_IRQHandler( void ) +#else +void ACE_PPE_Flag16_IRQHandler( void ) +#endif +{ + process_flag_irq( THRESHOLD_FLAG16 ); + NVIC_ClearPendingIRQ( ACE_PPE_Flag16_IRQn ); +} + +/*-------------------------------------------------------------------------*//** + * + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag17_IRQHandler( void ) +#else +void ACE_PPE_Flag17_IRQHandler( void ) +#endif +{ + process_flag_irq( THRESHOLD_FLAG17 ); + NVIC_ClearPendingIRQ( ACE_PPE_Flag17_IRQn ); +} + +/*-------------------------------------------------------------------------*//** + * + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag18_IRQHandler( void ) +#else +void ACE_PPE_Flag18_IRQHandler( void ) +#endif +{ + process_flag_irq( THRESHOLD_FLAG18 ); + NVIC_ClearPendingIRQ( ACE_PPE_Flag18_IRQn ); +} + +/*-------------------------------------------------------------------------*//** + * + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag19_IRQHandler( void ) +#else +void ACE_PPE_Flag19_IRQHandler( void ) +#endif +{ + process_flag_irq( THRESHOLD_FLAG19 ); + NVIC_ClearPendingIRQ( ACE_PPE_Flag19_IRQn ); +} + +/*-------------------------------------------------------------------------*//** + * + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag20_IRQHandler( void ) +#else +void ACE_PPE_Flag20_IRQHandler( void ) +#endif +{ + process_flag_irq( THRESHOLD_FLAG20 ); + NVIC_ClearPendingIRQ( ACE_PPE_Flag20_IRQn ); +} + +/*-------------------------------------------------------------------------*//** + * + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag21_IRQHandler( void ) +#else +void ACE_PPE_Flag21_IRQHandler( void ) +#endif +{ + process_flag_irq( THRESHOLD_FLAG21 ); + NVIC_ClearPendingIRQ( ACE_PPE_Flag21_IRQn ); +} + +/*-------------------------------------------------------------------------*//** + * + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag22_IRQHandler( void ) +#else +void ACE_PPE_Flag22_IRQHandler( void ) +#endif +{ + process_flag_irq( THRESHOLD_FLAG22 ); + NVIC_ClearPendingIRQ( ACE_PPE_Flag22_IRQn ); +} + +/*-------------------------------------------------------------------------*//** + * + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag23_IRQHandler( void ) +#else +void ACE_PPE_Flag23_IRQHandler( void ) +#endif +{ + process_flag_irq( THRESHOLD_FLAG23 ); + NVIC_ClearPendingIRQ( ACE_PPE_Flag23_IRQn ); +} + +/*-------------------------------------------------------------------------*//** + * + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag24_IRQHandler( void ) +#else +void ACE_PPE_Flag24_IRQHandler( void ) +#endif +{ + process_flag_irq( THRESHOLD_FLAG24 ); + NVIC_ClearPendingIRQ( ACE_PPE_Flag24_IRQn ); +} + +/*-------------------------------------------------------------------------*//** + * + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag25_IRQHandler( void ) +#else +void ACE_PPE_Flag25_IRQHandler( void ) +#endif +{ + process_flag_irq( THRESHOLD_FLAG25 ); + NVIC_ClearPendingIRQ( ACE_PPE_Flag25_IRQn ); +} + +/*-------------------------------------------------------------------------*//** + * + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag26_IRQHandler( void ) +#else +void ACE_PPE_Flag26_IRQHandler( void ) +#endif +{ + process_flag_irq( THRESHOLD_FLAG26 ); + NVIC_ClearPendingIRQ( ACE_PPE_Flag26_IRQn ); +} + +/*-------------------------------------------------------------------------*//** + * + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag27_IRQHandler( void ) +#else +void ACE_PPE_Flag27_IRQHandler( void ) +#endif +{ + process_flag_irq( THRESHOLD_FLAG27 ); + NVIC_ClearPendingIRQ( ACE_PPE_Flag27_IRQn ); +} + +/*-------------------------------------------------------------------------*//** + * + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag28_IRQHandler( void ) +#else +void ACE_PPE_Flag28_IRQHandler( void ) +#endif +{ + process_flag_irq( THRESHOLD_FLAG28 ); + NVIC_ClearPendingIRQ( ACE_PPE_Flag28_IRQn ); +} + +/*-------------------------------------------------------------------------*//** + * + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag29_IRQHandler( void ) +#else +void ACE_PPE_Flag29_IRQHandler( void ) +#endif +{ + process_flag_irq( THRESHOLD_FLAG29 ); + NVIC_ClearPendingIRQ( ACE_PPE_Flag29_IRQn ); +} + +/*-------------------------------------------------------------------------*//** + * + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag30_IRQHandler( void ) +#else +void ACE_PPE_Flag30_IRQHandler( void ) +#endif +{ + process_flag_irq( THRESHOLD_FLAG30 ); + NVIC_ClearPendingIRQ( ACE_PPE_Flag30_IRQn ); +} + +/*-------------------------------------------------------------------------*//** + * + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void ACE_PPE_Flag31_IRQHandler( void ) +#else +void ACE_PPE_Flag31_IRQHandler( void ) +#endif +{ + process_flag_irq( THRESHOLD_FLAG31 ); + NVIC_ClearPendingIRQ( ACE_PPE_Flag31_IRQn ); +} + +#ifdef __cplusplus +} +#endif + diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/ace_sse.c b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/ace_sse.c new file mode 100644 index 000000000..eefb06b18 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/ace_sse.c @@ -0,0 +1,306 @@ +/******************************************************************************* + * (c) Copyright 2009 Actel Corporation. All rights reserved. + * + * SVN $Revision: 2905 $ + * SVN $Date: 2010-08-20 14:03:28 +0100 (Fri, 20 Aug 2010) $ + */ +#include "mss_ace.h" +#include "mss_ace_configurator.h" +#include "../../drivers_config/mss_ace/ace_handles.h" +#include "../../drivers_config/mss_ace/ace_config.h" + +#include "../../CMSIS/a2fxxxm3.h" +#include "../../CMSIS/mss_assert.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SSE_START 1uL +#define SSE_STOP 0uL + +#define NB_OF_ANALOG_BLOCKS 3u +#define SEE_RAM_WORD_SIZE 512 + +#define TS_ENABLE_MASK 0x01u +#define PPE_ENABLE_MASK 0x01u +#define ADC_RESET_MASK 0x10u +#define ADC_FIFO_CLR_MASK 0x04u +#define PDMA_DATAOUT_CLR_MASK 0x04u + + +/*-------------------------------------------------------------------------*//** + * + */ +extern ace_procedure_desc_t g_sse_sequences_desc_table[ACE_NB_OF_SSE_PROCEDURES]; + +/*-------------------------------------------------------------------------*//** + * + */ +sse_sequence_handle_t +ACE_get_sse_seq_handle +( + const uint8_t * p_sz_sequence_name +) +{ + uint16_t seq_idx; + sse_sequence_handle_t handle = INVALID_SSE_SEQ_HANDLE; + + for ( seq_idx = 0u; seq_idx < (uint32_t)ACE_NB_OF_SSE_PROCEDURES; ++seq_idx ) + { + if ( g_sse_sequences_desc_table[seq_idx].p_sz_proc_name != 0 ) + { + int32_t diff; + diff = strncmp( (const char *)p_sz_sequence_name, (const char *)g_sse_sequences_desc_table[seq_idx].p_sz_proc_name, MAX_PROCEDURE_NAME_LENGTH ); + if ( 0 == diff ) + { + /* channel name found. */ + handle = seq_idx; + break; + } + } + } + return handle; +} + +/*-------------------------------------------------------------------------*//** + * + */ +static uint32_t volatile * const sse_pc_ctrl_lut[NB_OF_ANALOG_BLOCKS] = +{ + &ACE->PC0_CTRL, + &ACE->PC1_CTRL, + &ACE->PC2_CTRL +}; + +static uint32_t volatile * const sse_pc_lo_lut[NB_OF_ANALOG_BLOCKS] = +{ + &ACE->PC0_LO, + &ACE->PC1_LO, + &ACE->PC2_LO +}; + +static uint32_t volatile * const sse_pc_hi_lut[NB_OF_ANALOG_BLOCKS] = +{ + &ACE->PC0_HI, + &ACE->PC1_HI, + &ACE->PC2_HI +}; + +/*-------------------------------------------------------------------------*//** + * + */ +void ACE_load_sse +( + sse_sequence_handle_t sequence +) +{ + ASSERT( sequence < (sse_sequence_handle_t)ACE_NB_OF_SSE_PROCEDURES ); + + if ( sequence < (sse_sequence_handle_t)ACE_NB_OF_SSE_PROCEDURES ) + { + uint16_t i; + uint16_t offset; + const uint16_t * p_ucode; + + ASSERT( g_sse_sequences_desc_table[sequence].sse_pc_id < NB_OF_ANALOG_BLOCKS ); + + if ( g_sse_sequences_desc_table[sequence].sse_pc_id < NB_OF_ANALOG_BLOCKS ) + { + /* Stop relevant program counter. */ + *sse_pc_ctrl_lut[g_sse_sequences_desc_table[sequence].sse_pc_id] = SSE_STOP; + + /* Load microcode into SEE RAM.*/ + p_ucode = g_sse_sequences_desc_table[sequence].sse_ucode; + offset = g_sse_sequences_desc_table[sequence].sse_load_offset; + + for ( i = 0u; i < g_sse_sequences_desc_table[sequence].sse_ucode_length; ++i ) + { + ACE->SSE_RAM_DATA[offset + i] = (uint32_t)*p_ucode; + ++p_ucode; + } + } + } +} + + +/*-------------------------------------------------------------------------*//** + * + */ +void ACE_start_sse +( + sse_sequence_handle_t sequence +) +{ + ASSERT( sequence < (sse_sequence_handle_t)ACE_NB_OF_SSE_PROCEDURES ); + + if ( sequence < (sse_sequence_handle_t)ACE_NB_OF_SSE_PROCEDURES ) + { + uint16_t pc; + + ASSERT( g_sse_sequences_desc_table[sequence].sse_pc_id < NB_OF_ANALOG_BLOCKS ); + ASSERT( g_sse_sequences_desc_table[sequence].sse_load_offset < SEE_RAM_WORD_SIZE ); + + pc = g_sse_sequences_desc_table[sequence].sse_load_offset; + + if ( pc < 256u ) + { + *sse_pc_lo_lut[g_sse_sequences_desc_table[sequence].sse_pc_id] = pc; + } + else + { + *sse_pc_hi_lut[g_sse_sequences_desc_table[sequence].sse_pc_id] = pc - 256; + } + + *sse_pc_ctrl_lut[g_sse_sequences_desc_table[sequence].sse_pc_id] = SSE_START; + + /* Enable Sample Sequencing Engine in case it was not done as part of + * system boot. */ + ACE->SSE_TS_CTRL |= TS_ENABLE_MASK; + } +} + +/*-------------------------------------------------------------------------*//** + * + */ +void ACE_restart_sse +( + sse_sequence_handle_t sequence +) +{ + ASSERT( sequence < ACE_NB_OF_SSE_PROCEDURES ); + ASSERT( g_sse_sequences_desc_table[sequence].sse_pc_id < NB_OF_ANALOG_BLOCKS ); + ASSERT( g_sse_sequences_desc_table[sequence].sse_load_offset < SEE_RAM_WORD_SIZE ); + + if ( sequence < (sse_sequence_handle_t)ACE_NB_OF_SSE_PROCEDURES ) + { + uint16_t pc; + + pc = g_sse_sequences_desc_table[sequence].sse_loop_pc; + + if ( pc < 256u ) + { + *sse_pc_lo_lut[g_sse_sequences_desc_table[sequence].sse_pc_id] = pc; + } + else + { + *sse_pc_hi_lut[g_sse_sequences_desc_table[sequence].sse_pc_id] = pc - 256; + } + + *sse_pc_ctrl_lut[g_sse_sequences_desc_table[sequence].sse_pc_id] = SSE_START; + } +} + +/*-------------------------------------------------------------------------*//** + * + */ +void ACE_stop_sse +( + sse_sequence_handle_t sequence +) +{ + ASSERT( sequence < ACE_NB_OF_SSE_PROCEDURES ); + + if ( sequence < (sse_sequence_handle_t)ACE_NB_OF_SSE_PROCEDURES ) + { + /* Stop relevant program counter. */ + *sse_pc_ctrl_lut[g_sse_sequences_desc_table[sequence].sse_pc_id] = SSE_STOP; + } +} + +/*-------------------------------------------------------------------------*//** + * + */ +void ACE_resume_sse +( + sse_sequence_handle_t sequence +) +{ + ASSERT( sequence < ACE_NB_OF_SSE_PROCEDURES ); + + if ( sequence < (sse_sequence_handle_t)ACE_NB_OF_SSE_PROCEDURES ) + { + *sse_pc_ctrl_lut[g_sse_sequences_desc_table[sequence].sse_pc_id] = SSE_START; + } +} + +/*-------------------------------------------------------------------------*//** + * + */ +void ACE_enable_sse_irq +( + sse_irq_id_t sse_irq_id +) +{ + ASSERT( sse_irq_id < NB_OF_SSE_FLAG_IRQS ); + + ACE->SSE_IRQ_EN |= 1uL << (uint32_t)sse_irq_id; +} + +/*-------------------------------------------------------------------------*//** + * + */ +void ACE_disable_sse_irq +( + sse_irq_id_t sse_irq_id +) +{ + ASSERT( sse_irq_id < NB_OF_SSE_FLAG_IRQS ); + + ACE->SSE_IRQ_EN &= (uint32_t)~(1uL << (uint32_t)sse_irq_id); +} + +/*-------------------------------------------------------------------------*//** + * + */ +void ACE_clear_sse_irq +( + sse_irq_id_t sse_irq_id +) +{ + ASSERT( sse_irq_id < NB_OF_SSE_FLAG_IRQS ); + + ACE->SSE_IRQ_CLR |= 1uL << (uint32_t)sse_irq_id; +} + +/*-------------------------------------------------------------------------*//** + * + */ +void ACE_clear_sample_pipeline(void) +{ + uint32_t saved_sse_ctrl; + uint32_t saved_ppe_ctrl; + + /* Pause the Sample Sequencing Engine. */ + saved_sse_ctrl = ACE->SSE_TS_CTRL; + ACE->SSE_TS_CTRL = ACE->SSE_TS_CTRL & ~((uint32_t)TS_ENABLE_MASK); + + /* Pause the Post Processing Engine. */ + saved_ppe_ctrl = ACE->PPE_CTRL; + ACE->PPE_CTRL = ACE->PPE_CTRL & ~((uint32_t)PPE_ENABLE_MASK); + + /* Reset the ADCs */ + ACE->ADC0_MISC_CTRL |= ADC_RESET_MASK; + ACE->ADC1_MISC_CTRL |= ADC_RESET_MASK; + ACE->ADC2_MISC_CTRL |= ADC_RESET_MASK; + + /* Clear ADC FIFOs */ + ACE->ADC0_FIFO_CTRL |= ADC_FIFO_CLR_MASK; + ACE->ADC1_FIFO_CTRL |= ADC_FIFO_CLR_MASK; + ACE->ADC2_FIFO_CTRL |= ADC_FIFO_CLR_MASK; + + /* clear DMA FIFOs */ + ACE->PPE_PDMA_CTRL |= PDMA_DATAOUT_CLR_MASK; + + /* Unpause the Post Processing Engine. */ + ACE->PPE_CTRL = saved_ppe_ctrl; + + /* Unpause the Sample Sequencing Engine. */ + ACE->SSE_TS_CTRL = saved_sse_ctrl; +} + +#ifdef __cplusplus +} +#endif + diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/ace_transform.c b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/ace_transform.c new file mode 100644 index 000000000..0a44a6aae --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/ace_transform.c @@ -0,0 +1,467 @@ +/******************************************************************************* + * (c) Copyright 2010 Actel Corporation. All rights reserved. + * + * This file contains the implementation of the functions used to dynamically + * control the linear transforms applied by the ACE post processing engine to + * the samples read from the SSE. + * + * SVN $Revision: 2908 $ + * SVN $Date: 2010-08-20 16:01:28 +0100 (Fri, 20 Aug 2010) $ + */ + +#include "mss_ace.h" +#include "mss_ace_configurator.h" +#include "mtd_data.h" +#include "envm_layout.h" +#include "../../CMSIS/a2fxxxm3.h" +#include "../../CMSIS/mss_assert.h" +#include "../../drivers_config/mss_ace/ace_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The ACE_set_linear_transform() is only available when using ACE configuration + * files generated by Libero 9.1 or later. + */ +#ifdef ACE_CFG_DATA_FORMAT_VERSION + +/*------------------------------------------------------------------------------ + * Masks ans shift values used to derive the ABPS ranges from the analog block + * configuration. + */ +#define ABPS1_CFG_BITS_MASK (uint32_t)0x06 +#define ABPS1_CFG_BITS_SHIFT (uint32_t)1 + +#define ABPS2_CFG_BITS_MASK (uint32_t)0x60 +#define ABPS2_CFG_BITS_SHIFT (uint32_t)5 + +/*------------------------------------------------------------------------------ + * One Bit DAC definitions. + */ +#define OBD_CURRENT (uint32_t)1 +#define OBD_VOLTAGE (uint32_t)0 + +#define OBD_MODE_MASK (uint32_t)0x01 +#define OBD_CHOPPING_MASK (uint32_t)0x02 + +/*-------------------------------------------------------------------------*//** + Neutral factor and offset for m*x + c trnasform. + */ +#define NEUTRAL_M_FACTOR 0x4000 +#define NEUTRAL_C_OFFSET 0x0000 + +/*-------------------------------------------------------------------------*//** + Enumearation of the various input channel types. This is used to differentiate + between channel types in order to extract the relevant factory calibration + data(m1 and c1). + */ +typedef enum channel_type +{ + ABPS1_CHAN = 0, + ABPS2_CHAN, + CMB_CHAN, + TMB_CHAN, + DIRECT_ADC_INPUT_CHAN, + OBDOUT_CHAN, + FLOATING_CHAN +} cal_channel_type_t; + +/*-------------------------------------------------------------------------*//** + This data structure is used to store factory calibration data for a specific + analog input. + */ +typedef struct __channel_calibration_t +{ + uint16_t mext; + uint16_t m1; + uint16_t c1; +} channel_calibration_t; + +/*-------------------------------------------------------------------------*//** + Local functions + */ +int32_t extend_sign +( + uint16_t x +); + +uint32_t adjust_to_24bit_ace_format +( + int64_t signed48 +); + +uint32_t adjust_to_16bit_ace_format +( + int64_t signed48 +); + +void get_calibration +( + adc_channel_id_t channel_id, + channel_calibration_t * p_calibration +); + +void write_transform_coefficients +( + ace_channel_handle_t channel_handle, + uint32_t m, + uint32_t c +); + +/*-------------------------------------------------------------------------*//** + + */ +extern const uint8_t g_ace_external_varef_used[ACE_NB_OF_ADC]; + +extern ace_channel_desc_t g_ace_channel_desc_table[ACE_NB_OF_INPUT_CHANNELS]; + +extern const ppe_transforms_desc_t g_ace_ppe_transforms_desc_table[ACE_NB_OF_INPUT_CHANNELS]; + +/*------------------------------------------------------------------------------ + * Pointer to the manufacturing test data containing trimming information + * generated during manufacturing. + */ +static const mtd_data_t * const p_mtd_data = (mtd_data_t *)MTD_ADDRESS; + +/*-------------------------------------------------------------------------*//** + See "mss_ace.h" for details of how to use this function. + */ +int16_t ACE_get_default_m_factor +( + ace_channel_handle_t channel_handle +) +{ + ASSERT( channel_handle < NB_OF_ACE_CHANNEL_HANDLES ); + + return g_ace_ppe_transforms_desc_table[channel_handle].m_ppe_offset; +} + +/*-------------------------------------------------------------------------*//** + See "mss_ace.h" for details of how to use this function. + */ +int16_t ACE_get_default_c_offset +( + ace_channel_handle_t channel_handle +) +{ + ASSERT( channel_handle < NB_OF_ACE_CHANNEL_HANDLES ); + + return g_ace_ppe_transforms_desc_table[channel_handle].c_ppe_offset; +} + +/*-------------------------------------------------------------------------*//** + See "mss_ace.h" for details of how to use this function. + + m = m2 * m1 * mext + c = (m2 * c1 * mext) + (c2 * mext) + */ +void ACE_set_linear_transform +( + ace_channel_handle_t channel_handle, + int16_t m2, + int16_t c2 +) +{ + adc_channel_id_t channel_id; + uint32_t m; + uint32_t c; + int32_t m32; + int64_t m64; + int32_t c32; + int64_t c64_1; + int64_t c64_2; + uint16_t m1; + uint16_t c1; + uint16_t mext; + + channel_calibration_t calibration; + + ASSERT( channel_handle < NB_OF_ACE_CHANNEL_HANDLES ); + + if(channel_handle < NB_OF_ACE_CHANNEL_HANDLES) + { + channel_id = g_ace_channel_desc_table[channel_handle].signal_id; + + get_calibration(channel_id, &calibration); + + m1 = calibration.m1; + c1 = calibration.c1; + + mext = calibration.mext; + + /* + * m = m2 * m1 * mext + */ + m32 = extend_sign(m2) * extend_sign(m1); + m64 = (int64_t)m32 * extend_sign(mext); + + /* Convert 48-bit result to 32-bit ACE format result. */ + m = adjust_to_16bit_ace_format(m64); + + /* + * c = (m2 * c1 * mext) + (c2 * mext) + */ + c32 = extend_sign(m2) * extend_sign(c1); + c64_1 = (int64_t)c32 * extend_sign(mext); + + c64_2 = ((int64_t)(extend_sign(c2) * extend_sign(mext))) << 14; + + c = adjust_to_24bit_ace_format(c64_1 + c64_2); + + write_transform_coefficients(channel_handle, m, c); + } +} + +/*-------------------------------------------------------------------------*//** + Extend 16-bit signed number to 32-bit signed number. + */ +int32_t extend_sign +( + uint16_t x +) +{ + int32_t y; + const uint32_t sign_bit_mask = 0x00008000u; + + y = (x ^ sign_bit_mask) - sign_bit_mask; + + return y; +} + +/*-------------------------------------------------------------------------*//** + Take a 48-bit signed number, adjust it for saturation in the range -8 to + +7.999, translate into 24-bit ACE format. + */ +uint32_t adjust_to_24bit_ace_format +( + int64_t signed48 +) +{ + int32_t ace24_format; + const int64_t MAX_POSITIVE = 0x00001FFFFFFFFFFFuLL; /* +7.9999 */ + const int64_t MIN_NEGATIVE = 0xFFFF200000000000uLL; /* -8 */ + + /* Check saturation. */ + if(signed48 > MAX_POSITIVE) + { + signed48 = MAX_POSITIVE; + } + else if(signed48 < MIN_NEGATIVE) + { + signed48 = MIN_NEGATIVE; + } + + /* Adjust to 24-bit ACE format. */ + ace24_format = (uint32_t)(signed48 >> 14); + + return ace24_format; +} + +/*-------------------------------------------------------------------------*//** + Take a 48-bit signed number, adjust it for saturation in the range -8 to + +7.999, translate into 16-bit ACE format. + */ +uint32_t adjust_to_16bit_ace_format +( + int64_t signed48 +) +{ + int32_t ace24_format; + const int64_t MAX_POSITIVE = 0x00001FFFFFFFFFFFuLL; /* +7.9999 */ + const int64_t MIN_NEGATIVE = 0xFFFF200000000000uLL; /* -8 */ + + /* Check saturation. */ + if(signed48 > MAX_POSITIVE) + { + signed48 = MAX_POSITIVE; + } + else if(signed48 < MIN_NEGATIVE) + { + signed48 = MIN_NEGATIVE; + } + + /* Adjust to 24-bit ACE format. */ + ace24_format = (uint32_t)(signed48 >> 20); + + return ace24_format; +} + +/*-------------------------------------------------------------------------*//** + + */ +void get_calibration +( + adc_channel_id_t channel_id, + channel_calibration_t * p_calibration +) +{ + const uint32_t channel_mask = 0x0000000F; + const uint32_t CMB_MUX_SEL_MASK = 0x01; + const uint32_t TMB_MUX_SEL_MASK = 0x01; + + const cal_channel_type_t channel_type_lut[16] = + { + FLOATING_CHAN, + ABPS1_CHAN, + ABPS2_CHAN, + CMB_CHAN, + TMB_CHAN, + ABPS1_CHAN, + ABPS2_CHAN, + CMB_CHAN, + TMB_CHAN, + DIRECT_ADC_INPUT_CHAN, + DIRECT_ADC_INPUT_CHAN, + DIRECT_ADC_INPUT_CHAN, + DIRECT_ADC_INPUT_CHAN, + FLOATING_CHAN, + FLOATING_CHAN, + OBDOUT_CHAN + }; + + cal_channel_type_t channel_type; + uint32_t channel_nb; + uint32_t adc_nb; + uint32_t range; + uint32_t quad_id; + mtd_calibration_mc_t const * p_mc_coeff = 0; + + channel_nb = channel_id & channel_mask; + channel_type = channel_type_lut[channel_nb]; + adc_nb = ((uint32_t)channel_id & 0x30u) >> 4u; + + quad_id = adc_nb * 2; + + if ( (channel_nb > 4) && (channel_nb < 9) ) { ++quad_id; } + + switch ( channel_type ) + { + case ABPS1_CHAN: + range = (ACE->ACB_DATA[quad_id].b8 & ABPS1_CFG_BITS_MASK) >> ABPS1_CFG_BITS_SHIFT; + p_mc_coeff = &p_mtd_data->abps_calibration[quad_id][0][range]; + break; + + case ABPS2_CHAN: + range = (ACE->ACB_DATA[quad_id].b8 & ABPS2_CFG_BITS_MASK) >> ABPS2_CFG_BITS_SHIFT; + p_mc_coeff = &p_mtd_data->abps_calibration[quad_id][1][range]; + break; + + case CMB_CHAN: + { + uint32_t cmb_mux_sel = (uint32_t)ACE->ACB_DATA[quad_id].b9 & CMB_MUX_SEL_MASK; + if ( cmb_mux_sel == 0 ) + { /* current monitor */ + p_mc_coeff = &p_mtd_data->cm_calibration[quad_id]; + } + else + { /* direct input */ + p_mc_coeff = &p_mtd_data->quads_direct_input_cal[quad_id][0]; + } + } + break; + + case TMB_CHAN: + { + uint32_t tmb_mux_sel = (uint32_t)ACE->ACB_DATA[quad_id].b10 & TMB_MUX_SEL_MASK; + if ( tmb_mux_sel == 0 ) + { /* temperature monitor */ + p_mc_coeff = &p_mtd_data->tm_calibration[quad_id]; + } + else + { /* direct input */ + p_mc_coeff = &p_mtd_data->quads_direct_input_cal[quad_id][1]; + } + } + break; + + case DIRECT_ADC_INPUT_CHAN: + { + const uint32_t channel_to_direct_in_lut[16] + = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0}; + uint32_t direct_in_id; + + direct_in_id = channel_to_direct_in_lut[channel_id & channel_mask]; + p_mc_coeff = &p_mtd_data->adc_direct_input_cal[adc_nb][direct_in_id]; + } + break; + + case OBDOUT_CHAN: + { + uint32_t obd_mode = (uint32_t)ACE->ACB_DATA[quad_id].b6 & OBD_MODE_MASK; + uint32_t chopping_option = (uint32_t)ACE->ACB_DATA[quad_id].b6 & OBD_CHOPPING_MASK; + if (obd_mode > 0) + { + obd_mode = 1; + } + if (chopping_option > 0) + { + chopping_option = 1; + } + p_mc_coeff = &p_mtd_data->obd_calibration[adc_nb][obd_mode][chopping_option]; + } + break; + + case FLOATING_CHAN: + default: + /* Give neutral values is invalid channel. */ + p_calibration->m1 = NEUTRAL_M_FACTOR; + p_calibration->c1 = NEUTRAL_C_OFFSET; + break; + } + + if (p_mc_coeff != 0) + { + p_calibration->m1 = p_mc_coeff->m; + p_calibration->c1 = p_mc_coeff->c; + + } + + /*-------------------------------------------------------------------------- + Retrieve the value of the mext factor. This depends if external VAREF is + used by the ADC sampling the analog input channel. + */ + if (g_ace_external_varef_used[adc_nb]) + { + p_calibration->mext = p_mtd_data->global_settings.varef_m; + } + else + { + p_calibration->mext = NEUTRAL_M_FACTOR; + } +} + +/*-------------------------------------------------------------------------*//** + Write new m and c transform factors into the PPE RAM. The m and c factors + should be in 32-bit ACE number format. The factors will be merged with + relevant PE opcode into PPE RAM. The 32-bit factors are shifted right by one + byte giving a 24-bit ACE number which is then merged with an 8-bit PPE opcode + located in the most significant byte of the PPE RAM location. + */ +void write_transform_coefficients +( + ace_channel_handle_t channel_handle, + uint32_t m, + uint32_t c +) +{ + uint16_t m_ppe_offset; + uint16_t c_ppe_offset; + const uint32_t PPE_OPCODE_MASK = 0xFF000000u; + + m_ppe_offset = g_ace_ppe_transforms_desc_table[channel_handle].m_ppe_offset; + c_ppe_offset = g_ace_ppe_transforms_desc_table[channel_handle].c_ppe_offset; + + ACE->PPE_RAM_DATA[m_ppe_offset] + = (ACE->PPE_RAM_DATA[m_ppe_offset] & PPE_OPCODE_MASK) | (m >> 8u); + + ACE->PPE_RAM_DATA[c_ppe_offset] + = (ACE->PPE_RAM_DATA[c_ppe_offset] & PPE_OPCODE_MASK) | (c >> 8u); +} + +#endif /* ACE_CFG_DATA_FORMAT_VERSION */ + +#ifdef __cplusplus +} +#endif diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/envm_layout.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/envm_layout.h new file mode 100644 index 000000000..0081310d7 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/envm_layout.h @@ -0,0 +1,37 @@ +/******************************************************************************* + * (c) Copyright 2009 Actel Corporation. All rights reserved. + * + * This file contains the addresses and size of the various blocks of data + * stored in eNVM. + * + * SVN $Revision: 1113 $ + * SVN $Date: 2009-07-01 11:11:29 +0100 (Wed, 01 Jul 2009) $ + */ +#ifndef ENVM_LAYOUT_HEADER +#define ENVM_LAYOUT_HEADER + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================== + * Address of the manufacturing test data. + */ +#define MTD_ADDRESS 0x60080010 + +/*============================================================================== + * MSS configuration location. + */ +#define MSS_CONFIG_ADDRESS 0x60081618 + +/*============================================================================== + * Analog configuration location and size. + */ +#define ANALOG_CONFIG_ADDRESS 0x60081600 +#define ANALOG_CONFIG_BYTE_SIZE 24 + +#ifdef __cplusplus +} +#endif + +#endif /* ENVM_LAYOUT_HEADER */ diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/mss_ace.c b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/mss_ace.c new file mode 100644 index 000000000..cd717f036 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/mss_ace.c @@ -0,0 +1,744 @@ +/******************************************************************************* + * (c) Copyright 2009 Actel Corporation. All rights reserved. + * + * SVN $Revision: 2905 $ + * SVN $Date: 2010-08-20 14:03:28 +0100 (Fri, 20 Aug 2010) $ + */ + +#include "mss_ace.h" +#include "mtd_data.h" +#include "envm_layout.h" +#include "mss_ace_configurator.h" +#include "../../CMSIS/a2fxxxm3.h" +#include "../../CMSIS/mss_assert.h" +#include "../../drivers_config/mss_ace/ace_config.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define START_ADC_CONVERSION 0x80uL + + +/**/ +void ace_init_flags( void ); +void ace_init_convert(void); + +/*-------------------------------------------------------------------------*//** + See "mss_ace.h" for details of how to use this function. + */ +void ACE_init( void ) +{ + /* Initialize driver's internal data. */ + ace_init_flags(); + + /* Initialize the data structures used by conversion functions. */ + ace_init_convert(); +} + +/*-------------------------------------------------------------------------*//** + See "mss_ace.h" for details of how to use this function. + */ +void ACE_start_adc +( + adc_channel_id_t channel_id +) +{ + ACE->ADC0_CONV_CTRL = (uint32_t)channel_id | START_ADC_CONVERSION; +} + +/*-------------------------------------------------------------------------*//** + See "mss_ace.h" for details of how to use this function. + */ +#define ADC_DATAVALID_MASK 0x00001000uL +#define ADC_RESULT_MASK 0x00000FFFuL + +static const uint32_t volatile * const adc_status_reg_lut[NB_OF_ANALOG_MODULES] = +{ + &ACE->ADC0_STATUS, + &ACE->ADC1_STATUS, + &ACE->ADC2_STATUS +}; + +uint16_t ACE_get_adc_result +( + uint8_t adc_id +) +{ + uint16_t result = 0u; + uint32_t data_valid; + + ASSERT( adc_id < NB_OF_ANALOG_MODULES ); + + if ( adc_id < (uint8_t)NB_OF_ANALOG_MODULES ) + { + do { + data_valid = *adc_status_reg_lut[adc_id] & ADC_DATAVALID_MASK; + } while ( !data_valid ); + + result = (uint16_t)(*adc_status_reg_lut[adc_id] & ADC_RESULT_MASK); + } + return result; +} + +/*============================================================================== + =========== Sigma Delta Digital to Analog Converters (SDD) Control ============ + =============================================================================*/ + +#define SDD_ENABLE_MASK 0x20uL +#define SDD_REG_SEL_MASK 0x40uL + +#define DAC0_SYNC_EN_MASK 0x10uL +#define DAC1_SYNC_EN_MASK 0x20uL +#define DAC2_SYNC_EN_MASK 0x40uL + +#define DAC0_SYNC_UPDATE 0x01uL +#define DAC1_SYNC_UPDATE 0x02uL +#define DAC2_SYNC_UPDATE 0x04uL + +/*-------------------------------------------------------------------------*//** + * + */ +static volatile uint32_t * const dac_ctrl_reg_lut[NB_OF_ANALOG_MODULES] = +{ + &ACE->DAC0_CTRL, + &ACE->DAC1_CTRL, + &ACE->DAC1_CTRL +}; + +static const uint32_t dac_enable_masks_lut[NB_OF_ANALOG_MODULES] = +{ + DAC0_SYNC_EN_MASK, + DAC1_SYNC_EN_MASK, + DAC2_SYNC_EN_MASK +}; + +static volatile uint32_t * const dac_byte01_reg_lut[NB_OF_ANALOG_MODULES] = +{ + &ACE->SSE_DAC0_BYTES01, + &ACE->SSE_DAC1_BYTES01, + &ACE->SSE_DAC2_BYTES01, +}; + +static volatile uint32_t * const dac_byte2_reg_lut[NB_OF_ANALOG_MODULES] = +{ + &ACE->DAC0_BYTE2, + &ACE->DAC1_BYTE2, + &ACE->DAC2_BYTE2 +}; + +/*------------------------------------------------------------------------------ + * Pointer to the manufacturing test data containing trimming information + * generated during manufacturing. + */ +static const mtd_data_t * const p_mtd_data = (mtd_data_t *)MTD_ADDRESS; + +/*-------------------------------------------------------------------------*//** + See "mss_ace.h" for details of how to use this function. + */ +#define OBD_MODE_MASK (uint8_t)0x01 +#define OBD_CHOPPING_MASK (uint8_t)0x02 + +void ACE_configure_sdd +( + sdd_id_t sdd_id, + sdd_resolution_t resolution, + uint8_t mode, + sdd_update_method_t sync_update +) +{ + ASSERT( sdd_id < NB_OF_SDD ); + + if ( sdd_id < NB_OF_SDD ) + { + const uint8_t sdd_2_quad_lut[NB_OF_SDD] = {0u, 2u, 4u}; + uint8_t quad_id; + uint8_t obd_mode_idx = 1u; + uint8_t chopping_mode_idx = 0u; + uint32_t saved_pc2_ctrl; + + quad_id = sdd_2_quad_lut[sdd_id]; + + /* Pause the SSE PC2 while accesses to ACB from APB3 are taking place. */ + saved_pc2_ctrl = ACE->PC2_CTRL; + ACE->PC2_CTRL = 0u; + + /* Select between voltage/current and RTZ modes.*/ + ACE->ACB_DATA[quad_id].b6 = mode; + + /* Load manufacturing generated trim value. */ + if ( (mode & OBD_MODE_MASK) > 0u ) + { + obd_mode_idx = 0u; + } + if ( (mode & OBD_CHOPPING_MASK) > 0u ) + { + chopping_mode_idx = 1u; + } + ACE->ACB_DATA[quad_id].b4 + = p_mtd_data->odb_trimming[sdd_id][obd_mode_idx][chopping_mode_idx]; + + /* Restore SSE PC2 operations since no ACB accesses should take place + * beyond this point. */ + ACE->PC2_CTRL = saved_pc2_ctrl; + + /* Set SDD resolution. */ + *dac_ctrl_reg_lut[sdd_id] = (uint32_t)resolution; + + /* Update SDD value through SSE_DACn_BYTES01. */ + *dac_ctrl_reg_lut[sdd_id] |= SDD_REG_SEL_MASK; + + /* Synchronous or individual SDD update. */ + if ( INDIVIDUAL_UPDATE == sync_update ) + { + ACE->DAC_SYNC_CTRL &= ~dac_enable_masks_lut[sdd_id]; + } + else + { + ACE->DAC_SYNC_CTRL |= dac_enable_masks_lut[sdd_id]; + } + } +} + +/*-------------------------------------------------------------------------*//** + See "mss_ace.h" for details of how to use this function. + */ +void ACE_enable_sdd +( + sdd_id_t sdd_id +) +{ + ASSERT( sdd_id < NB_OF_SDD ); + + if ( sdd_id < NB_OF_SDD ) + { + *dac_ctrl_reg_lut[sdd_id] |= SDD_ENABLE_MASK; + } +} + +/*-------------------------------------------------------------------------*//** + See "mss_ace.h" for details of how to use this function. + */ +void ACE_disable_sdd +( + sdd_id_t sdd_id +) +{ + ASSERT( sdd_id < NB_OF_SDD ); + + if ( sdd_id < NB_OF_SDD ) + { + *dac_ctrl_reg_lut[sdd_id] &= ~SDD_ENABLE_MASK; + } +} + +/*-------------------------------------------------------------------------*//** + See "mss_ace.h" for details of how to use this function. + */ +void ACE_set_sdd_value +( + sdd_id_t sdd_id, + uint32_t sdd_value +) +{ + ASSERT( sdd_id < NB_OF_SDD ); + + if ( sdd_id < NB_OF_SDD ) + { + *dac_byte2_reg_lut[sdd_id] = sdd_value >> 16; + *dac_byte01_reg_lut[sdd_id] = sdd_value; + } +} + +/*-------------------------------------------------------------------------*//** + See "mss_ace.h" for details of how to use this function. + */ +void ACE_set_sdd_value_sync +( + uint32_t sdd0_value, + uint32_t sdd1_value, + uint32_t sdd2_value +) +{ + uint32_t dac_sync_ctrl; + + dac_sync_ctrl = ACE->DAC_SYNC_CTRL; + + if ( SDD_NO_UPDATE != sdd0_value ) + { + ACE->DAC0_BYTE2 = sdd0_value >> 16; + ACE->SSE_DAC0_BYTES01 = sdd0_value; + dac_sync_ctrl |= DAC0_SYNC_UPDATE; + } + + if ( SDD_NO_UPDATE != sdd1_value ) + { + ACE->DAC1_BYTE2 = sdd1_value >> 16; + ACE->SSE_DAC1_BYTES01 = sdd1_value; + dac_sync_ctrl |= DAC1_SYNC_UPDATE; + } + + if ( SDD_NO_UPDATE != sdd2_value ) + { + ACE->DAC2_BYTE2 = sdd2_value >> 16; + ACE->DAC2_BYTE1 = sdd2_value >> 8; + ACE->SSE_DAC2_BYTES01 = sdd2_value; + dac_sync_ctrl |= DAC2_SYNC_UPDATE; + } + + ACE->DAC_SYNC_CTRL = dac_sync_ctrl; +} + +/*============================================================================== + ============================ Comparators Control ============================== + =============================================================================*/ + + /* + * SDD Analog switch mask. ACB byte 10. + * 0: TMB comparator reference voltage is an ADC direct input + * 1: TMB comparator reference voltage is one of the SDD outputs as + * selected by DAC_MUXSEL[1:0] + */ +#define B10_COMP_VREF_SW_MASK 0x20u + +/* + * Comparator reference voltage multiplexer. + * Used to select which SDD output will be used as reference voltage for TMB + * comparator. These bits are only meaningful when COMP_VREF_SW is set to 1. + */ +#define B11_DAC_MUXSEL_MASK 0x03u + +/* + * Number of bits to shift a value of type comp_hysteresis_t to get the + * hysteresis to program into ACB b9 or b10. + */ +#define HYSTERESIS_SHIFT 6u + +/* + * Mask of hysteresis bits within ACB b9 or b10. + */ +#define HYSTERESIS_MASK 0xC0u + +/* + * Mask of the comparator enable bit within ACB b9 and b10. + */ +#define COMPARATOR_ENABLE_MASK 0x10u + +/* + * Comparator ID to Signal Conditioning Block (SCB) lookup table. + * USe to find which SCB a comparator belongs to. + */ +const uint8_t comp_id_2_scb_lut[NB_OF_COMPARATORS] = +{ + 0u, /* CMP0 */ + 0u, /* CMP1 */ + 1u, /* CMP2 */ + 1u, /* CMP3 */ + 2u, /* CMP4 */ + 2u, /* CMP5 */ + 3u, /* CMP6 */ + 3u, /* CMP7 */ + 4u, /* CMP8 */ + 4u, /* CMP9 */ + 5u, /* CMP10 */ + 5u /* CMP11 */ +}; + +/*-------------------------------------------------------------------------*//** + * This function is requred to configure comparators included in temperature + * monitor blocks. + */ +void ACE_set_comp_reference +( + comparator_id_t comp_id, + comp_reference_t reference +) +{ + uint8_t scb_id; + uint32_t odd; + + odd = (uint32_t)comp_id & 0x01uL; + + ASSERT( comp_id < NB_OF_COMPARATORS ); + ASSERT( reference < NB_OF_COMP_REF ); + ASSERT( odd ); /* Only Temperature block comparators have configurable reference input. */ + + if ( (comp_id < NB_OF_COMPARATORS) && (reference < NB_OF_COMP_REF) && (odd) ) + { + uint32_t saved_pc2_ctrl; + + scb_id = comp_id_2_scb_lut[comp_id]; + + /* Pause the SSE PC2 while accesses to ACB from APB3 are taking place. */ + saved_pc2_ctrl = ACE->PC2_CTRL; + ACE->PC2_CTRL = 0u; + + if ( ADC_IN_COMP_REF == reference ) + { + ACE->ACB_DATA[scb_id].b10 &= (uint8_t)~B10_COMP_VREF_SW_MASK; + ACE->ACB_DATA[scb_id].b11 &= (uint8_t)~B11_DAC_MUXSEL_MASK; + } + else + { + ACE->ACB_DATA[scb_id].b10 &= (uint8_t)~B10_COMP_VREF_SW_MASK; + ACE->ACB_DATA[scb_id].b11 = (ACE->ACB_DATA[scb_id].b11 & (uint8_t)~B11_DAC_MUXSEL_MASK) + (uint8_t)reference; + } + + /* Restore SSE PC2 operations since no ACB accesses should take place + * beyond this point. */ + ACE->PC2_CTRL = saved_pc2_ctrl; + } +} + +/*-------------------------------------------------------------------------*//** + * Set analog block comparators hysteresis. + */ +void ACE_set_comp_hysteresis +( + comparator_id_t comp_id, + comp_hysteresis_t hysteresis +) +{ + uint8_t scb_id; + + ASSERT( comp_id < NB_OF_COMPARATORS ); + ASSERT( hysteresis < NB_OF_HYSTERESIS ); + + if ( (comp_id < NB_OF_COMPARATORS) && (hysteresis < NB_OF_HYSTERESIS) ) + { + uint32_t odd; + uint32_t saved_pc2_ctrl; + + scb_id = comp_id_2_scb_lut[comp_id]; + odd = (uint32_t)comp_id & 0x01uL; + + /* Pause the SSE PC2 while accesses to ACB from APB3 are taking place. */ + saved_pc2_ctrl = ACE->PC2_CTRL; + ACE->PC2_CTRL = 0u; + + if ( odd ) + { + /* Temperature monitor block comparator. */ + ACE->ACB_DATA[scb_id].b10 = (ACE->ACB_DATA[scb_id].b10 & HYSTERESIS_MASK) | (uint8_t)((uint8_t)hysteresis << HYSTERESIS_SHIFT); + } + else + { + /* Current monitor block comparator. */ + ACE->ACB_DATA[scb_id].b9 = (ACE->ACB_DATA[scb_id].b9 & HYSTERESIS_MASK) | (uint8_t)((uint8_t)hysteresis << HYSTERESIS_SHIFT); + } + + /* Restore SSE PC2 operations since no ACB accesses should take place + * beyond this point. */ + ACE->PC2_CTRL = saved_pc2_ctrl; + } +} + +/*-------------------------------------------------------------------------*//** + + */ +void ACE_enable_comp +( + comparator_id_t comp_id +) +{ + uint8_t scb_id; + + ASSERT( comp_id < NB_OF_COMPARATORS ); + + if ( comp_id < NB_OF_COMPARATORS ) + { + uint32_t odd; + uint32_t saved_pc2_ctrl; + + scb_id = comp_id_2_scb_lut[comp_id]; + odd = (uint32_t)comp_id & 0x01uL; + + /* Pause the SSE PC2 while accesses to ACB from APB3 are taking place. */ + saved_pc2_ctrl = ACE->PC2_CTRL; + ACE->PC2_CTRL = 0u; + + if ( odd ) + { + /* Temperature monitor block comparator. */ + ACE->ACB_DATA[scb_id].b10 |= COMPARATOR_ENABLE_MASK; + } + else + { + /* Current monitor block comparator. */ + ACE->ACB_DATA[scb_id].b9 |= COMPARATOR_ENABLE_MASK; + } + + /* Restore SSE PC2 operations since no ACB accesses should take place + * beyond this point. */ + ACE->PC2_CTRL = saved_pc2_ctrl; + } +} + +/*-------------------------------------------------------------------------*//** + * + */ +void ACE_disable_comp +( + comparator_id_t comp_id +) +{ + uint8_t scb_id; + + ASSERT( comp_id < NB_OF_COMPARATORS ); + + if ( comp_id < NB_OF_COMPARATORS ) + { + uint32_t odd; + uint32_t saved_pc2_ctrl; + + scb_id = comp_id_2_scb_lut[comp_id]; + odd = (uint32_t)comp_id & 0x01uL; + + /* Pause the SSE PC2 while accesses to ACB from APB3 are taking place. */ + saved_pc2_ctrl = ACE->PC2_CTRL; + ACE->PC2_CTRL = 0u; + + if ( odd ) + { + /* Temperature monitor block comparator. */ + ACE->ACB_DATA[scb_id].b10 &= (uint8_t)~COMPARATOR_ENABLE_MASK; + } + else + { + /* Current monitor block comparator. */ + ACE->ACB_DATA[scb_id].b9 &= (uint8_t)~COMPARATOR_ENABLE_MASK; + } + + /* Restore SSE PC2 operations since no ACB accesses should take place + * beyond this point. */ + ACE->PC2_CTRL = saved_pc2_ctrl; + } +} + +/* + * Bit mask of comparator 0 rise interrupt bit. + * Shift this value left by the value of the comparator ID to obtain the bit + * mask used enable/disable/clear rise interrupts from that comparator. + */ +#define FIRST_RISE_IRQ_MASK 0x00000800uL + +/* + * Bit mask of comparator 0 fall interrupt bit. + * Shift this value left by the value of the comparator ID to obtain the bit + * mask used enable/disable/clear fall interrupts from that comparator. + */ +#define FIRST_FALL_IRQ_MASK 0x00000001uL + +/*-------------------------------------------------------------------------*//** + See "mss_ace.h" for details of how to use this function. + */ +void ACE_enable_comp_rise_irq +( + comparator_id_t comp_id +) +{ + ASSERT( comp_id < NB_OF_COMPARATORS ); + + ACE->COMP_IRQ_EN |= (FIRST_RISE_IRQ_MASK << (uint32_t)comp_id); +} + +/*-------------------------------------------------------------------------*//** + See "mss_ace.h" for details of how to use this function. + */ +void ACE_disable_comp_rise_irq +( + comparator_id_t comp_id +) +{ + ASSERT( comp_id < NB_OF_COMPARATORS ); + + ACE->COMP_IRQ_EN &= ~(FIRST_RISE_IRQ_MASK << (uint32_t)comp_id); +} + +/*-------------------------------------------------------------------------*//** + See "mss_ace.h" for details of how to use this function. + */ +void ACE_clear_comp_rise_irq +( + comparator_id_t comp_id +) +{ + ASSERT( comp_id < NB_OF_COMPARATORS ); + + ACE->COMP_IRQ_CLR |= (FIRST_RISE_IRQ_MASK << (uint32_t)comp_id); +} + +/*-------------------------------------------------------------------------*//** + See "mss_ace.h" for details of how to use this function. + */ +void ACE_enable_comp_fall_irq +( + comparator_id_t comp_id +) +{ + ASSERT( comp_id < NB_OF_COMPARATORS ); + + ACE->COMP_IRQ_EN |= (FIRST_FALL_IRQ_MASK << (uint32_t)comp_id); +} + +/*-------------------------------------------------------------------------*//** + See "mss_ace.h" for details of how to use this function. + */ +void ACE_disable_comp_fall_irq +( + comparator_id_t comp_id +) +{ + ASSERT( comp_id < NB_OF_COMPARATORS ); + + ACE->COMP_IRQ_EN &= ~(FIRST_FALL_IRQ_MASK << (uint32_t)comp_id); +} + +/*-------------------------------------------------------------------------*//** + See "mss_ace.h" for details of how to use this function. + */ +void ACE_clear_comp_fall_irq +( + comparator_id_t comp_id +) +{ + ASSERT( comp_id < NB_OF_COMPARATORS ); + + ACE->COMP_IRQ_CLR |= (FIRST_FALL_IRQ_MASK << (uint32_t)comp_id); +} + +/*-------------------------------------------------------------------------*//** + * Returns the raw analog quad comparator status. + */ +uint32_t ACE_get_comp_status( void ) +{ + return ACE->COMP_IRQ; +} + +/*============================================================================== + ============ Reading Samples from post processing engine (PPE) ================ + =============================================================================*/ +extern ace_channel_desc_t g_ace_channel_desc_table[ACE_NB_OF_INPUT_CHANNELS]; + +/*-------------------------------------------------------------------------*//** + See "mss_ace.h" for details of how to use this function. + */ +uint32_t +ACE_get_channel_count +( + void +) +{ + return (uint32_t)ACE_NB_OF_INPUT_CHANNELS; +} + +/*-------------------------------------------------------------------------*//** + See "mss_ace.h" for details of how to use this function. + */ +ace_channel_handle_t +ACE_get_first_channel +( + void +) +{ + ace_channel_handle_t channel_handle; + + channel_handle = (ace_channel_handle_t)0; + + return channel_handle; +} + +/*-------------------------------------------------------------------------*//** + See "mss_ace.h" for details of how to use this function. + */ +ace_channel_handle_t +ACE_get_next_channel +( + ace_channel_handle_t channel_handle +) +{ + ++channel_handle; + + if ( channel_handle >= NB_OF_ACE_CHANNEL_HANDLES ) + { + channel_handle = (ace_channel_handle_t)0; + } + + return channel_handle; +} + +/*-------------------------------------------------------------------------*//** + See "mss_ace.h" for details of how to use this function. + */ +ace_channel_handle_t +ACE_get_channel_handle +( + const uint8_t * p_sz_channel_name +) +{ + uint16_t channel_idx; + ace_channel_handle_t channel_handle = INVALID_CHANNEL_HANDLE; + + for ( channel_idx = 0u; channel_idx < (uint16_t)ACE_NB_OF_INPUT_CHANNELS; ++channel_idx ) + { + if ( g_ace_channel_desc_table[channel_idx].p_sz_channel_name != 0 ) + { + int32_t diff; + diff = strncmp( (const char*)p_sz_channel_name, (const char*)g_ace_channel_desc_table[channel_idx].p_sz_channel_name, MAX_CHANNEL_NAME_LENGTH ); + if ( 0 == diff ) + { + /* channel name found. */ + channel_handle = (ace_channel_handle_t)channel_idx; + break; + } + } + } + return channel_handle; +} + +/*-------------------------------------------------------------------------*//** + See "mss_ace.h" for details of how to use this function. + */ +ace_channel_handle_t +ACE_get_input_channel_handle +( + adc_channel_id_t channel_id +) +{ + uint16_t channel_idx; + ace_channel_handle_t channel_handle = INVALID_CHANNEL_HANDLE; + + for ( channel_idx = 0u; channel_idx < (uint16_t)ACE_NB_OF_INPUT_CHANNELS; ++channel_idx ) + { + if ( g_ace_channel_desc_table[channel_idx].signal_id == channel_id ) + { + /* channel ID found. */ + channel_handle = (ace_channel_handle_t)channel_idx; + break; + } + } + return channel_handle; +} + +/*-------------------------------------------------------------------------*//** + See "mss_ace.h" for details of how to use this function. + */ +uint16_t +ACE_get_ppe_sample +( + ace_channel_handle_t channel_handle +) +{ + uint16_t sample; + uint16_t ppe_offset; + + ppe_offset = g_ace_channel_desc_table[channel_handle].signal_ppe_offset; + sample = (uint16_t)(ACE->PPE_RAM_DATA[ppe_offset] >> 16u); + + return sample; +} + +#ifdef __cplusplus +} +#endif diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/mss_ace.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/mss_ace.h new file mode 100644 index 000000000..ec4f00ed7 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/mss_ace.h @@ -0,0 +1,2816 @@ +/******************************************************************************* + * (c) Copyright 2009 Actel Corporation. All rights reserved. + * + * SmartFusion ACE driver public API. + * + * SVN $Revision: 2884 $ + * SVN $Date: 2010-08-13 16:16:59 +0100 (Fri, 13 Aug 2010) $ + */ + +/*=========================================================================*//** + @mainpage SmartFusion Analog Compute Engine driver public API. + + @section intro_sec Introduction + The SmartFusion™ microcontroller subsystem (MSS) includes the Analog Compute + Engine (ACE) which provides access to the analog capabilities of SmartFusion + from the Cortex™-M3 microcontroller. This driver provides a set of functions + for controlling the MSS ACE as part of a bare metal system where no operating + system is available. These drivers can be adapted for use as part of an + operating system, but the implementation of the adaptation layer between this + driver and the operating system's driver model is outside the scope of this + driver. The ACE includes: + • A Sample Sequencing Engine (SSE) controlling the operations of up to + three analog to digital converters (ADC) + • A Post Processing Engine (PPE) processing the analog inputs samples + generated as a result of the SSE operations + • An interface for controlling Sigma Delta DACs (SDD) + • An interface for controlling high speed comparators + + The Sample Sequencing Engine controls the sampling of the various analog + inputs based on a predefined sampling sequence without requiring intervention + from the Cortex-M3. The sampling sequence is defined using the ACE Configurator + provided as part of the MSS Configurator software tool. + Available analog inputs are: + • Active bipolar prescaler inputs (ABPS) allowing to measure voltages within + four possible ranges: + o -15V to +15V + o -10V to +10V + o -5V to +5V + o -2.5V to +2.5V + • Current inputs + • Temperature inputs + • Direct ADC inputs allowing to measure a voltage between zero volts and + the ADC’s reference voltage (VAREF) + Please refer to the Analog Front End section of the SmartFusion datasheet for + further details about analog inputs. + + The Post Processing Engine can perform the following operations on the analog + input samples generated as a result of the SSE operations: + • Calibration adjustment + • Averaging + • Threshold detection + • DMA transfer of most recent sample result to RAM or FPGA fabric + The result of analog input sampling is read from the PPE rather than directly + from the ADC. This ensures more accurate sample results thought the factory + calibration adjustment performed by the PPE. + The PPE can be set to generate interrupts when specific threshold values are + reached on analog inputs through the ACE Configurator software tool. These + thresholds can also be dynamically adjusted through the ACE driver. + + The ACE provides an interface to the Sigma Delta DACs included within the + Analog Front End (AFE). This interface allows control of the DAC’s output + value. Dynamic configuration of the DAC is also possible. + + The ACE provides an interface to the high speed comparators included within + the Analog Front End. This interface allows dynamic configuration of the + comparators and controlling interrupts based on the comparators’ state. + + @section theory_op Theory of Operation + The configuration of the ACE is set though the use of the ACE Configurator + included in the SmartFusion MSS Configurator software tool provided as part of + the Libero Integrated Design Environment tool suite. The ACE Configurator + offers an easy to use graphical method of selecting the configuration of the + following ACE characteristics: + • Analog input channels configuration + • ADC configuration + • Analog input channels sampling sequence + • Filtering applied to analog input samples + • Threshold flags configuration including hysteresis or state filtering properties + • Selection of post processing results transferred though DMA + • Sigma Delta DACs configuration + • Analog comparators configuration + The selected configuration hardware settings, SSE microcode and PPE microcode + are stored in the SmartFusion eNVM. This configuration data is used by the + system boot to configure the ACE after the system come out of reset and before + control is passed to the application. This results in the ACE being fully + operational by the time the application starts executing. + The ACE Configurator also generates a set of C files containing information + about the ACE’s configuration. These C files must be copied into the + drivers_config/mss_ace folder of you r software project for consumption by the + ACE driver. The ACE driver uses the content of these configuration files to + interact with the configured ACE hardware. + + The ACE driver functions are grouped into the following categories: + • Initialization + • Reading analog input channels values and properties + • Post Processing Engine flags + • Conversion functions between sample value and real world units + • Sample Sequencing Engine control + • Sample Sequencing Engine Interrupts Control + • Comparators control + • Sigma Delta Digital to Analog Converters (SDD) control + • Direct analog block configuration and usage + + + Initialization + The ACE driver is initialized through a call to the ACE_init() function. The + ACE_init() function must be called before any other ACE driver functions can + be called. It initializes the ACE’s internal data. + + + Reading analog input channels values and properties + The ACE driver allows retrieving the most recent post processed sample value + for each analog input. It also allows retrieving the name of the analog input + channel assigned in the ACE Configurator and whether the input channel samples + a voltage, current or temperature. + Each individual analog input channel is identified using a channel handle which + is passed as parameter to the ACE input channel driver functions. The channel + handles are design specific. The list of channel handles is generated by the + ACE Configurator based on the names given to the input signals. The channel + handles can be found in the drivers_config\mss_ace\ace_handles.h file. The + channel handle can be obtained from the channel name using the ACE_get_channel_handle() + function. It is also possible to iterate through all the channels using the + ACE_get_first_channel() and ACE_get_next_channel() functions. + + Reading analog input samples from the post processing engine is done the following function: + • uint16_t ACE_get_ppe_sample( ace_channel_handle_t channel_handle ) + + Information about an input channel can be retrieved using the following functions: + • const uint8_t * ACE_get_channel_name( ace_channel_handle_t channel_handle ) + • channel_type_t ACE_get_channel_type( ace_channel_handle_t channel_handle ) + + + Post Processing Engine flags + The SmartFusion ACE Post Processing Engine (PPE) provides the ability to monitor + the state of analog input channels and detect when certain threshold values are + crossed. Flags are raised by the PPE when these thresholds are crossed. Interrupts + can optionally be generated when flags are raised. + The flags are defined using the ACE Configurator software tool. The flag’s name, + threshold value and hysteresis settings are specified in the ACE Configurator. + The ACE Configurator generates microcode based on the selected configuration which + is executed at system run time by the PPE. The PPE microcode is loaded into the + ACE at chip boot time by the Actel provided system boot code. No ACE driver + intervention is required to load up the PPE microcode. + The ACE driver allows: + • Retrieving the current state of the post processing engine flags + • Assigning a handler function to individual flag assertions + • Assigning a handler function to flags generated based on the value of a + specific channel + • Controlling flag interrupts + • Dynamically modify a flag’s threshold value + • Dynamically modify a flag’s hysteresis + + Each individual flag is identified using a flag handle which is passed as parameter + to the ACE driver functions controlling the flags. The flag handles are design + specific. They are defined in the drivers_config\mss_ace\ace_handles.h file which + is generated by the ACE Configurator based on the names selected for the signal + and flag names. A flag handle can be obtained from the driver using the name of + the flag entered in the ACE Configurator software when the flag was created. A + flag handle can also be obtained using the functions ACE_get_channel_first_flag() + and ACE_get_channel_next_flag() when iterating through the flags associated with + an analog input channel. The functions available for retrieving flag handles are: + • ace_flag_handle_t ACE_get_flag_handle (const uint8_t *p_sz_full_flag_name) + • ace_flag_handle_t ACE_get_channel_first_flag (ace_channel_handle_t channel_handle, uint16_t *iterator) + • ace_flag_handle_t ACE_get_channel_next_flag (ace_channel_handle_t channel_handle, uint16_t *iterator) + + The current status of a flag can be polled using the following function: + • int32_t ACE_get_flag_status (ace_flag_handle_t flag_handle) + + Interrupt handlers can be registered with the ACE driver to handle individual + flags. These interrupt handlers will be called by the ACE driver when a specific + flag is raised. The flag interrupt control functions are: + • void ACE_register_flag_isr (ace_flag_handle_t flag_handle, flag_isr_t flag_isr) + • void ACE_enable_flag_irq (ace_flag_handle_t flag_handle) + • void ACE_disable_flag_irq (ace_flag_handle_t flag_handle) + • void ACE_clear_flag_irq (ace_flag_handle_t flag_handle) + + Interrupt handlers can be registered with the ACE driver to handle all flags + associated with one specific analog input channel. These interrupt handlers will + be called by the ACE driver when one of the flags, generated based on the state of + the specified analog input channel, is raised. The channel flag interrupt control + functions are: + • void ACE_register_channel_flags_isr (ace_channel_handle_t channel_handle, channel_flag_isr_t channel_flag_isr) + • void ACE_enable_channel_flags_irq (ace_channel_handle_t channel_handle) + • void ACE_disable_channel_flags_irq (ace_channel_handle_t channel_handle) + • void ACE_clear_channel_flags_irq (ace_channel_handle_t channel_handle) + + A single global interrupt handler can be registered with the ACE driver. The global + flag interrupt handler function will be called by the ACE driver when any of the + interrupt enabled flag is raised. The handle of the flag causing the interrupt and + the handle of the associated analog input channel is passed as parameter to the + registered global flag handler. + • void ACE_register_global_flags_isr (global_flag_isr_t global_flag_isr) + + The configuration of a flag can be dynamically modified using the following functions: + • void ACE_set_flag_threshold (ace_flag_handle_t flag_handle, uint16_t new_threshold) + • void ACE_set_flag_hysteresis (ace_flag_handle_t flag_handle, uint16_t adc_hysteresis) + • void ACE_set_channel_hysteresis (ace_channel_handle_t channel_handle, uint16_t adc_hysteresis) + • void ACE_set_flag_assertion( ace_flag_handle_t flag_handle, uint16_t assertion_value ) + • void ACE_set_flag_deassertion( ace_flag_handle_t flag_handle, uint16_t assertion_value ) + + Information about a flag can be retrieved using the following functions once + the flag handle is known: + • const uint8_t * ACE_get_flag_name (ace_flag_handle_t flag_handle) + • ace_channel_handle_t ACE_get_flag_channel (ace_flag_handle_t flag_handle) + + + Conversion to and from real world units + The ACE driver provides a set of conversion functions to convert sample values + read from the post processing engine into real world units: + • millivolts + • milliamps + • Degrees Kelvin + • Degrees Celsius + • Degrees Fahrenheit + Conversion functions are also available to convert from real world units into + PPE sample values. These functions are typically used for dynamically adjusting + flags threshold values. + + + Sample Sequencing Engine control + The ACE driver provides a set of functions for dynamically controlling the + Sample Sequencing Engine. These functions are only required for managing multiple + sampling sequences. The use of these functions is not required for most applications + since the SSE is already configured and running by the time the application starts. + + + Sample Sequencing Engine Interrupts Control + The ACE driver provides a set of functions for managing interrupts generated by + the Sample Sequencing Engine. These functions allow enabling, disabling and clearing + interrupt defined as part of the sampling sequence. These functions also allow + controlling interrupts generated by the ADCs. + + + Comparators control + The ACE driver provides a set of functions for managing interrupts generated based + on the change of state of the high speed comparators. Functions are also provided + to dynamically modify the comparators configuration. + + + Sigma Delta Digital to Analog Converters (SDD) control + The ACE driver provides functions for controlling the output value of the Sigma + Delta DACs (SDD). Functions are also provided for dynamically adjusting the + configuration of the SDDs. + + *//*=========================================================================*/ +#ifndef __MSS_ACE_H_ +#define __MSS_ACE_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../../drivers_config/mss_ace/ace_handles.h" + +/*-------------------------------------------------------------------------*//** + Analog to Digital Converter channel IDs. + This enumeration is used to identify the ADC's analog inputs. It caters for up + to three ADCs/Analog Modules as can be found on the larger parts of the + SmartFusion family. The channel ID numbering is designed to allow easy + extraction of the ADC number and also the individual ADC input number by simple + shifting and masking. This enumeration is used as parameter to the + ACE_get_input_channel_handle() function retrieving the channel handle associated + with a specific analog input signal. + */ +typedef enum +{ + ADC0_1P5V = 0, /*!< Analog Module 0, 1.5V/GND */ + ABPS0 = 1, /*!< Analog Module 0, Quad0 Active Bipolar Pre-Scaler input 1 */ + ABPS1 = 2, /*!< Analog Module 0, Quad0 Active Bipolar Pre-Scaler input 2 */ + CM0 = 3, /*!< Analog Module 0, Quad0 Current Monitor Block */ + TM0 = 4, /*!< Analog Module 0, Quad0 Temperature Monitor Block */ + ABPS2 = 5, /*!< Analog Module 0, Quad1 Active Bipolar Pre-Scaler input 1 */ + ABPS3 = 6, /*!< Analog Module 0, Quad1 Active Bipolar Pre-Scaler input 2 */ + CM1 = 7, /*!< Analog Module 0, Quad1 Current Monitor Block */ + TM1 = 8, /*!< Analog Module 0, Quad1 Temperature Monitor Block */ + ADC0 = 9, /*!< Analog Module 0 Direct Input 0 */ + ADC1 = 10, /*!< Analog Module 0 Direct Input 1 */ + ADC2 = 11, /*!< Analog Module 0 Direct Input 2 */ + ADC3 = 12, /*!< Analog Module 0 Direct Input 3 */ + SDD0_IN = 15, /*!< Analog Module 0 Sigma-Delta DAC output */ + + ADC1_1P5V = 16, /*!< Analog Module 1, 1.5V/GND */ + ABPS4 = 17, /*!< Analog Module 1, Quad0 Active Bipolar Pre-Scaler input 1 */ + ABPS5 = 18, /*!< Analog Module 1, Quad0 Active Bipolar Pre-Scaler input 2 */ + CM2 = 19, /*!< Analog Module 1, Quad0 Current Monitor Block */ + TM2 = 20, /*!< Analog Module 1, Quad0 Temperature Monitor Block */ + ABPS6 = 21, /*!< Analog Module 1, Quad1 Active Bipolar Pre-Scaler input 1 */ + ABPS7 = 22, /*!< Analog Module 1, Quad1 Active Bipolar Pre-Scaler input 2 */ + CM3 = 23, /*!< Analog Module 1, Quad1 Current Monitor Block */ + TM3 = 24, /*!< Analog Module 1, Quad1 Temperature Monitor Block */ + ADC4 = 25, /*!< Analog Module 1 Direct Input 0 */ + ADC5 = 26, /*!< Analog Module 1 Direct Input 1 */ + ADC6 = 27, /*!< Analog Module 1 Direct Input 2 */ + ADC7 = 28, /*!< Analog Module 1 Direct Input 3 */ + SDD1_IN = 31, /*!< Analog Module 1 Sigma-Delta DAC output */ + + ADC2_1P5V = 32, /*!< Analog Module 2, 1.5V/GND */ + ABPS8 = 33, /*!< Analog Module 2, Quad0 Active Bipolar Pre-Scaler input 1 */ + ABPS9 = 34, /*!< Analog Module 2, Quad0 Active Bipolar Pre-Scaler input 2 */ + CM4 = 35, /*!< Analog Module 2, Quad0 Current Monitor Block */ + TM4 = 36, /*!< Analog Module 2, Quad0 Temperature Monitor Block */ + ABPS10 = 37, /*!< Analog Module 2, Quad1 Active Bipolar Pre-Scaler input 1 */ + ABPS11 = 38, /*!< Analog Module 2, Quad1 Active Bipolar Pre-Scaler input 2 */ + CM5 = 39, /*!< Analog Module 2, Quad1 Current Monitor Block */ + TM5 = 40, /*!< Analog Module 2, Quad1 Temperature Monitor Block */ + ADC8 = 41, /*!< Analog Module 2 Direct Input 0 */ + ADC9 = 42, /*!< Analog Module 2 Direct Input 1 */ + ADC10 = 43, /*!< Analog Module 2 Direct Input 2 */ + ADC11 = 44, /*!< Analog Module 2 Direct Input 3 */ + SDD2_IN = 47, /*!< Analog Module 2 Sigma-Delta DAC output */ + INVALID_CHANNEL = 255 /*!< Used to indicate errors */ +} adc_channel_id_t; + + +/*-------------------------------------------------------------------------*//** + The ACE_init() function initializes the SmartFusion MSS ACE driver. It + initializes the ACE driver’s internal data structures. The ACE_init() function + must be called before any other MSS ACE driver functions can be called. + */ +void ACE_init( void ); + + +/*============================================================================== + ============== Direct Analog Block Configuration and Usage ==================== + =============================================================================*/ + +/*=========================================================================*//** + @defgroup group1 Direct Analog Block Configuration and Usage + These functions are intended for using the SmartFusion analog block hardware + without relying on the Sampling Sequence Engine or Post Processing engine. + @{ + *//*=========================================================================*/ + +/*-------------------------------------------------------------------------*//** + The ACE_start_adc() function initiates the sampling of the analog input + channel identified by the channel_id parameter. This function is provided for + test purposes. It must not be used while the Sample Sequencing Engine is + running. + + @param channel_id + The channel_id parameter identifies the analog input channel to sample. + + @return + This function does not return a value. + */ +void ACE_start_adc +( + adc_channel_id_t channel_id +); + +/*-------------------------------------------------------------------------*//** + The ACE_get_adc_result () function reads the result of the last input channel + sampling performed by the ADC identified as parameter. + + @param adc_id + The adc_id parameter identifies which of the possible three ADC to read the + sample result from. + + @return + The ACE_start_adc_sync() function returns the ADC result from the ADC + specified as parameter. + */ +uint16_t ACE_get_adc_result +( + uint8_t adc_id +); + +/** @} */ + +/*============================================================================== + =========== Sigma Delta Digital to Analog Converters (SDD) Control ============ + =============================================================================*/ +/*=========================================================================*//** + @defgroup group2 Sigma Delta Digital to Analog Converters (SDD) Control + The following functions are used to control the Sigma Delta DACs included + within the SmartFusion analog block. + @{ + *//*=========================================================================*/ + +/*-------------------------------------------------------------------------*//** + The sdd_id_t enumeration is used to identify the Sigma Delta DACs to the SDD + control functions, ACE_configure_sdd(), ACE_enable_sdd(), ACE_disable_sdd() + and ACE_set_sdd_value(). There is one SDD per analog module. + */ +typedef enum +{ + SDD0_OUT = 0, /*!< Analog Module 0 Sigma Delta DAC */ + SDD1_OUT = 1, /*!< Analog Module 1 Sigma Delta DAC */ + SDD2_OUT = 2, /*!< Analog Module 2 Sigma Delta DAC */ + NB_OF_SDD = 3 +} sdd_id_t; + +/*-------------------------------------------------------------------------*//** + The sdd_resolution_t enumeration is used as a parameter to the + ACE_configure_sdd() function to specify DAC resolution of the Sigma Delta DAC. + */ +typedef enum +{ + SDD_8_BITS = 0, + SDD_16_BITS = 4, + SDD_24_BITS = 8 +} sdd_resolution_t; + +/*-------------------------------------------------------------------------*//** + These constant definitions are used as an argument to the ACE_configure_sdd() + function to specify operating mode of the Sigma Delta DAC. + */ +#define SDD_CURRENT_MODE 1 +#define SDD_VOLTAGE_MODE 0 +#define SDD_RETURN_TO_ZERO 0 +#define SDD_NON_RTZ 2 + +/*-------------------------------------------------------------------------*//** + The sdd_update_method_t enumeration is used as a parameter to the + ACE_configure_sdd() function to specify individual or synchronous updating of + the Sigma Delta DACs. + */ +typedef enum +{ + INDIVIDUAL_UPDATE = 0, + SYNC_UPDATE = 1 +} sdd_update_method_t; + +/*-------------------------------------------------------------------------*//** + The ACE_configure_sdd() function is used to configure the operating mode of + the Sigma Delta DAC (SDD) specified as parameter. It allows selecting whether the + SDD will output a voltage or a current. A current between 0 and 256uA is + generated in current mode. A voltage between 0 and 2.56V is generated in + voltage mode. + This function also allows selecting whether Return To Zero (RTZ) mode is + enabled or not. Enabling Return To Zero mode improves linearity of the SDD + output at the detriment of accuracy. This mode should be used if linearity is + more important than accuracy. + A call to this function is not required if relying on the configuration + selected in the ACE configurator being loaded after reset by the system boot. + + @param sdd_id + The sdd_id parameter specifies which Sigma Delta DAC is configured by this + function. Allowed values are: + - SDD0_OUT + - SDD1_OUT + - SDD2_OUT + + @param resolution + The resolution parameter specifies the desired resolution of the Sigma Delta DAC. + Allowed values are: + - SDD_8_BITS + - SDD_16_BITS + - SDD_24_BITS + + @param mode + The mode parameter specifies the operating mode of the Sigma Delta DAC. It + specifies whether a current or voltage should be generated and whether + Return to Zero mode should be used. It is a logical OR of the following + defines: + - SDD_CURRENT_MODE + - SDD_VOLTAGE_MODE + - SDD_RETURN_TO_ZERO + - SDD_NON_RTZ + + @param sync_update + The sync_update parameter specifies whether the SDD output will be updated + individually though a call to ACE_set_sdd_value() or synchronously with one + or more other SDD outputs via a call to ACE_set_sdd_value_sync(). + + Example + @code + ACE_configure_sdd + ( + SDD1_OUT, + SDD_24_BITS, + SDD_VOLTAGE_MODE | SDD_RETURN_TO_ZERO, + INDIVIDUAL_UPDATE + ); + @endcode + */ +void ACE_configure_sdd +( + sdd_id_t sdd_id, + sdd_resolution_t resolution, + uint8_t mode, + sdd_update_method_t sync_update +); + +/*-------------------------------------------------------------------------*//** + The ACE_enable_sdd() function is used to enable a Sigma Delta DAC. + + @param sdd_id + The sdd_id parameter specifies the Sigma Delta DAC to enable. + */ +void ACE_enable_sdd +( + sdd_id_t sdd_id +); + +/*-------------------------------------------------------------------------*//** + The ACE_disable_sdd() function is used to disable a Sigma Delta DAC. + + @param sdd_id + The sdd_id parameter specifies the Sigma Delta DAC to disable. + */ +void ACE_disable_sdd +( + sdd_id_t sdd_id +); + +/*-------------------------------------------------------------------------*//** + The ACE_set_sdd_value() function is used to set the value of the output of + a Sigma Delta DAC. It uses the ACE's phase accumulator to generate the one bit + input bit stream into the SDD which will in turn define the voltage or + current generated at the SDD output. + The SDD output is proportional to the sdd_value passed to this function taking + the SDD resolution into account. A maximum voltage of 2.56V or a maximum + current of 256uA will be generated when the sdd_value is set the maximum value + allowed by the SDD resolution + + @param sdd_id + The sdd_id parameter specifies which Sigma Delta DAC is being set. + + @param sdd_value + The sdd_value parameter specifies the value of the Sigma Delta DAC output. + It is a fraction of SDD resolution. The voltage/current value generated from + the sdd_value paramenter can be determined using the following equation where + sdd_resolution is the resolution of the SDD as set through function + ACE_configure_sdd() and sdd_rangSDD configuration: + sdd_output = (sdd_value / sdd_resolution) * sdd_range + */ +void ACE_set_sdd_value +( + sdd_id_t sdd_id, + uint32_t sdd_value +); + + +/*-------------------------------------------------------------------------*//** + This constant definition is used as an argument to the ACE_set_sdd_value_sync() + function to specify that the output value of SDD0, or SDD1, or SDD2 should not + be modified. + */ +#define SDD_NO_UPDATE 0xFFFFFFFF + +/*-------------------------------------------------------------------------*//** + The ACE_set_sdd_value_sync() function is used to synchronize the update of + multiple Sigma Delta DAC outputs. + + @param sdd0_value + The sdd0_value parameter specifies the value that will be used to set the + output of SDD0. + The define SDD_NO_UPDATE can be used to specify that the output value of + SDD0 should not be modified. + + @param sdd1_value + The sdd1_value parameter specifies the value that will be used to set the + output of SDD1. + The define SDD_NO_UPDATE can be used to specify that the output value of + SDD1 should not be modified. + + @param sdd2_value + The sdd2_value parameter specifies the value that will be used to set the + output of SDD2. + The define SDD_NO_UPDATE can be used to specify that the output value of + SDD2 should not be modified. + + For example the code below will change the output value of SDD0 and SDD2 so + that the voltage/current generate by SDD0 and ADD2 will change at the same + time. This function call will not affect the output value of SDD1. + @code + uint32_t sdd0_value = 0x1234; + uint32_t sdd2_value = 0x5678; + ACE_set_sdd_value_sync( sdd0_value, SDD_NO_UPDATE, sdd2_value ); + @endcode + */ + +void ACE_set_sdd_value_sync +( + uint32_t sdd0_value, + uint32_t sdd1_value, + uint32_t sdd2_value +); + +/** @} */ + +/*============================================================================== + ============ Reading Samples from post processing engine (PPE) ================ + =============================================================================*/ +/*=========================================================================*//** + @defgroup group9 Reading Analog Input Channels Values and Properties + The following functions are used to access analog input channels properties + and sampled values. + @{ + *//*=========================================================================*/ + +/*-------------------------------------------------------------------------*//** + This constant returned by the ACE_get_flag_channel(), ACE_get_channel_handle() + and ACE_get_input_channel_handle() functions when the driver can’t find a + valid handle for the ADC input channel. + */ +#define INVALID_CHANNEL_HANDLE NB_OF_ACE_CHANNEL_HANDLES + +/*-------------------------------------------------------------------------*//** + The ACE_get_channel_handle() function returns the channel handle associated + with an analog input channel name. The retrieved channel handle will be + subsequently used as parameter to function ACE_get_ppe_sample() used to read + the most recent post processed sample for the analog input identified through + the channel/service name passed as argument to this function. + + @param p_sz_channel_name + The p_sz_channel_name parameter is a zero-terminated string containing the + name of the channel/service as entered in the ACE configurator. + + @return + This function returns a channel handle. This channel handle is required as + parameter to function ACE_get_ppe_sample(). + It will return INVALID_CHANNEL_HANDLE if the channel/service name is not + recognized. + + @code + uint16_t adc_result; + ace_channel_handle_t at0; + at0 = ACE_get_channel_handle("VoltageMonitorAT0"); + adc_result = ACE_get_ppe_sample( at0 ); + @endcode + */ +ace_channel_handle_t +ACE_get_channel_handle +( + const uint8_t * p_sz_channel_name +); + +/*-------------------------------------------------------------------------*//** + The ACE_get_input_channel_handle() function returns the channel handle for + the hardware analog input channel specified as parameter. + + @param channel_id + The channel_id parameter identifies a hardware analog input of the ACE. + + @return + This function returns a channel handle. This channel handle is required as + parameter to other ACE driver functions dealing with analog inputs. + It will return INVALID_CHANNEL_HANDLE if the channel ID passed as parameter + is invalid. + */ +ace_channel_handle_t +ACE_get_input_channel_handle +( + adc_channel_id_t channel_id +); + +/*-------------------------------------------------------------------------*//** + The ACE_get_ppe_sample() function is used to read the most recent post + processed sample for the analog input channel associated with the channel + handle passed as parameter. + + @param channel_handle + The channel_handle parameter identifies the analog input channel for which + this function will return the most recent ADC conversion result adjusted for + calibration and user provided coefficients as provided through the ACE + configurator. The available channel handle values can be found in the + ace_handles.h file located in the ./drivers_config/mss_ace subdirectory. The + channel handle value can also be retrieved through a call to + ACE_get_channel_handle() when the name of the channel is known, or by + iterating though all analog input channel using the ACE_get_first_channel() + and ACE_get_next_channel(). + + @return + This function returns a 16 bit value representing the adjusted value of the + ADC conversion result for the analog input channel identified by the channel + handle passed as parameter. The return value is actually a 12, 10 or 8 bits + number depending on the configuration of the ADC. + + @code + uint16_t adc_result; + ace_channel_handle_t at0; + at0 = ACE_get_channel_handle("VoltageMonitorAT0"); + adc_result = ACE_get_ppe_sample( at0 ); + @endcode + */ +uint16_t +ACE_get_ppe_sample +( + ace_channel_handle_t channel_handle +); + +/*-------------------------------------------------------------------------*//** + The ACE_get_channel_name() function provides the name of the channel + associated with the channel handle passed as parameter. The channel name is + the name used in the ACE configurator software tool when adding a service to + the ACE. + + @param channel_handle + The channel_handle parameter identifies the analog input channel for which + we want to retrieve the channel name. The available channel handle values can + be found in the ace_handles.h file located in the ./drivers_config/mss_ace + subdirectory. The channel handle value can also be retrieved through a call + to ACE_get_channel_handle() when the name of the channel is known, or by + iterating though all analog input channel using the ACE_get_first_channel() + and ACE_get_next_channel(). + + @return + This function returns a pointer to a zero-terminated string containing the + name of the channel. It returns 0 if the channel handle passed as parameter + is not recognized. + */ +const uint8_t * ACE_get_channel_name +( + ace_channel_handle_t channel_handle +); + +/*-------------------------------------------------------------------------*//** + The channel_type_t enumeration is used to identify the type of quantity + measured by an analog input channel. It is typically used to figure out the + type of conversion that must be applied to the ADC value generated from + sampling a channel in order to yield real world units such millivolts, + milliamps or degrees. + */ +typedef enum +{ + VOLTAGE, + CURRENT, + TEMPERATURE +} channel_type_t; + +/*-------------------------------------------------------------------------*//** + The ACE_get_channel_type() function returns the type of input channel of the + analog input channel identified by the channel handle passed as parameter. + This function allows determining whether the quantity measured through the ADC + is a voltage, current or temperature. + + @param channel_handle + The channel_handle parameter identifies one of the analog input channels + monitored by the ACE. The available channel handle values can be found in the + ace_handles.h file located in the .\drivers_config\mss_ace subdirectory. The + channel handle value can also be retrieved through a call to + ACE_get_channel_handle() when the name of the channel is known, or by + iterating though all analog input channel using the ACE_get_first_channel() + and ACE_get_next_channel(). + + @return + This function returns one of the following values to report the type of + quantity measure throught the channel: + - VOLTAGE + - CURRENT + - TEMPERATURE + */ +channel_type_t +ACE_get_channel_type +( + ace_channel_handle_t channel_handle +); + +/*-------------------------------------------------------------------------*//** + The ACE_get_channel_count() function returns the total number of configured + analog input channels. It is the number of channels available for use as + opposed to the theorical number of physical channels supported by the device. + + @return + The ACE_get_channel_count() function returns the total number of input + channels that were configured in the ACE configurator. + The ACE_get_channel_count() function returns 0 if no input channels were + configured. + + @code + uint32_t inc; + uint32_t nb_of_channels; + ace_channel_handle_t current_channel; + + nb_of_channels = ACE_get_channel_count(); + current_channel = ACE_get_first_channel(); + + for (inc = 0; inc < nb_of_channels; ++inc) + { + adc_result = ACE_get_ppe_sample( current_channel ); + display_value( current_channel, adc_result ); + current_channel = ACE_get_next_channel( current_channel ); + } + @endcode + */ +uint32_t +ACE_get_channel_count +( + void +); + +/*-------------------------------------------------------------------------*//** + The ACE_get_first_channel() function returns the channel handle of one of the + channel controlled by the ACE. This function is used to start iterating though + the list of analog input channels handled by the ACE. + + @return + The ACE_get_first_channel() function returns the first channel handle found + in the ACE driver's internal channel handles list or INVALID_CHANNEL_HANDLE + if there are no channels defined in the ACE configuration. + + @code + uint32_t inc; + uint32_t nb_of_channels; + ace_channel_handle_t current_channel; + + nb_of_channels = ACE_get_channel_count(); + current_channel = ACE_get_first_channel(); + + for (inc = 0; inc < nb_of_channels; ++inc) + { + adc_result = ACE_get_ppe_sample( current_channel ); + display_value( current_channel, adc_result ); + current_channel = ACE_get_next_channel( current_channel ); + } + @endcode + */ +ace_channel_handle_t +ACE_get_first_channel +( + void +); + +/*-------------------------------------------------------------------------*//** + The ACE_get_next_channel() returns the channel handle of the channel following + the one passed as parameter. This function is used to iterate through the list + of analog input channels handled by the ACE. + + @param channel_handle + The channel_handle parameter identifies from which channel the driver should + look in its channel handle list to return the next channel handle. The + channel_handle parameter would typically be the channel handle returned by a + call to ACE_get_first_channel() or a previous call to ACE_get_next_channel(). + Note: + The first call to ACE_get_next_channel() would typically use the + channel_handle returned by a previous call to ACE_get_first_channel(). The + second and subsequent calls to ACE_get_next_channel() would typically use + the channel_handle returned by a previous call to ACE_get_next_channel(). + + @return + The ACE_get_next_channel() function returns the channel handle of the channel + following the one passed as parameter or INVALID_CHANNEL_HANDLE if the end of + the channels list has been reached. + + @code + uint32_t inc; + uint32_t nb_of_channels; + ace_channel_handle_t current_channel; + + nb_of_channels = ACE_get_channel_count(); + current_channel = ACE_get_first_channel(); + + for (inc = 0; inc < nb_of_channels; ++inc) + { + adc_result = ACE_get_ppe_sample( current_channel ); + display_value( current_channel, adc_result ); + current_channel = ACE_get_next_channel( current_channel ); + } + @endcode + */ +ace_channel_handle_t +ACE_get_next_channel +( + ace_channel_handle_t channel_handle +); + + /** @} */ + +/*============================================================================== + =============================== SSE Control ================================== + =============================================================================*/ +/*=========================================================================*//** + @defgroup group3 Sample Sequencing Engine Control + Sample Sequencing Engine control. + @{ + *//*=========================================================================*/ + +/*-------------------------------------------------------------------------*//** + The Sample Sequencing Engine control functions use a parameter of this type as + a handle to identify the Sample Sequencing Engine (SSE) sequences configured + using the ACE configurator. The ACE_get_sse_seq_handle() function retrieves the + handle of the SSE sequence identified by the sequence name passed as parameter. + Note: The ACE configurator generates ACE driver configuration files into the + .\drivers_config\mss_ace folder of the firmware project. These files + contain the details of the SSE sequence handles for your ACE configuration. + The ACE driver automatically includes these files when the + .\drivers_config\mss_ace folder is present in the firmware project. + */ +typedef uint16_t sse_sequence_handle_t; + +/*-------------------------------------------------------------------------*//** + This constant is returned by the ACE_get_sse_seq_handle() function when the + driver can’t find a valid handle for the Sample Sequencing Engine (SSE) sequence. +*/ +#define INVALID_SSE_SEQ_HANDLE 0xFFFFu + +/*-------------------------------------------------------------------------*//** + The ACE_get_sse_seq_handle() function retrieves the handle of the Sample + Sequencing Engine sequence identified by the sequence name passed as parameter. + The sequence handler can then be used as parameter to other SSE sequence control + functions to identify the sequence to control. + + @param p_sz_sequence_name + The p_sz_sequence_name parameter is a pointer to a zero-terminated string + containing the name of the sampling sequence for which we want to retrieve + the handle. + + @return + The ACE_get_sse_seq_handle() function returns the handle used to identify + the sequence passed as parameter with other ACE driver sampling sequence + control functions. It returns INVALID_SSE_SEQ_HANDLE if the sequence name + passed as parameter is not recognized. + + @code + sse_sequence_handle_t sse_seq_handle; + sse_seq_handle = ACE_get_sse_seq_handle("ProcedureA"); + if ( sse_seq_handle != INVALID_SSE_SEQ_HANDLE ) + { + ACE_load_sse( sse_seq_handle ); + ACE_start_sse( sse_seq_handle ); + } + @endcode + */ +sse_sequence_handle_t +ACE_get_sse_seq_handle +( + const uint8_t * p_sz_sequence_name +); + +/*-------------------------------------------------------------------------*//** + The ACE_load_sse() function loads the ACE Sample Sequencing Engine (SSE) RAM + with the microcode implementing the sampling sequence identified by the SSE + sequence handler passed as parameter. + + @param sequence + The sequence parameter is the SSE sequence handler identifying the sampling + sequence to load into the ACE SSE. The value for this handler is retrieved + through a call to function ACE_get_sse_seq_handle(). + */ +void ACE_load_sse +( + sse_sequence_handle_t sequence +); + +/*-------------------------------------------------------------------------*//** + The ACE_start_sse() function causes the Sampling Sequence Engine (SSE) to start + executing the sequence identified by the sequence handler passed as parameter. + It causes the initiailization part of the sampling sequence to be executed + before the loop part of the sequence is started. + You must ensure that the sampling sequence has been loaded into the ACE's SSE + before calling this function. + + @param sequence + The sequence parameter is the SSE sequence handler identifying the sampling + sequence to load into the ACE SSE. The value for this handler is retrieved + through a call to function ACE_get_sse_seq_handle(). + */ +void ACE_start_sse +( + sse_sequence_handle_t sequence +); + +/*-------------------------------------------------------------------------*//** + The ACE_restart_sse() function restarts the loop part of the sampling sequence + loaded into the ACE's Sampling Sequence Engine (SSE). The sampling sequence + will be restarted from the beginning of the sequence but omiting the + intialization phase of the sequence. + This function would typically be called after stopping the sampling sequence + using the ACE_stop_see() function or with non-repeating sequences. + + @param sequence + The sequence parameter is the SSE sequence handler identifying the sampling + sequence to load into the ACE SSE. The value for this handler is retrieved + through a call to function ACE_get_sse_seq_handle(). + */ +void ACE_restart_sse +( + sse_sequence_handle_t sequence +); + +/*-------------------------------------------------------------------------*//** + The ACE_stop_sse() function stops execution of the Sample Sequencing Engine + (SSE) sequence indentified by the sequence handle passed as parameter. + + @param sequence + The sequence parameter is the SSE sequence handle identifying the sampling + sequence to load into the ACE SSE. The value for this handler is retrieved + through a call to function ACE_get_sse_seq_handle(). + */ +void ACE_stop_sse +( + sse_sequence_handle_t sequence +); + +/*-------------------------------------------------------------------------*//** + The ACE_resume_sse() function causes the Sampling Sequencing Engine (SSE) + sampling sequence identified by the sequence handle passed as parameter to + resume execution. This function is typically used to restart execution of + a sequence at the point where it was stopped through a call to ACE_stop_sse(). + + @param sequence + The sequence parameter is the SSE sequence handler identifying the sampling + sequence to load into the ACE SSE. The value for this handler is retrieved + through a call to function ACE_get_sse_seq_handle(). + */ +void ACE_resume_sse +( + sse_sequence_handle_t sequence +); + +/*-------------------------------------------------------------------------*//** + The ACE_clear_sample_pipeline() function clears the ACE hardware of samples + being processed. It clear the various stages involved in the production of + post processed samples within the ACE hardware. It is intended for use when + switching between sampling sequences and using peripheral DMA. It avoids + receiving stale samples generated as a result of a previous sampling sequence. + + The example below shows how this function can be used to ensure that no sample + generated as a result of sampling sequence sequence_a will be generated once + sampling sequence_b is started. Please note that it is important to stop the + SSE using function ACE_stop_sse() before calling ACE_clear_sample_pipeline() + to ensure sequence_a is not restarted after the sample pipeline is cleared. + @code + ACE_stop_sse(sequence_a); + ACE_clear_sample_pipeline(); + ACE_start_sse(sequence_b); + @endcode + + The example below shows how to ensure that the first sample read through PDMA + will be from the first channel in the sampling sequence. + @code + ACE_stop_sse(sequence_a); + ACE_clear_sample_pipeline(); + ACE_restart_sse(sequence_a); + PDMA_start + ( + PDMA_CHANNEL_0, + PDMA_ACE_PPE_DATAOUT, + (uint32_t)g_samples_buffer[g_pdma_buffer_idx], + SAMPLES_BUFFER_SIZE + ); + @endcode + */ +void ACE_clear_sample_pipeline(void); + +/** @} */ +/*============================================================================== + ======================== SSE Interrupts Control =============================== + =============================================================================*/ +/*=========================================================================*//** + @defgroup group4 Sample Sequencing Engine Interrupts Control + The following functions are used to control interrupts generated from the + ACE's Sample Sequencing Engine. These interrupts would typically be used to + detect when valid data is available from the ADCs controlled by the SSE or to + detect the complete or partial completion of the sampling sequence through the + insertion of SSE program counter general purpose interrupt assertion as part + of the sequence. + @{ + *//*=========================================================================*/ + +/*-------------------------------------------------------------------------*//** + The sse_irq_id_t enumeration is used to identify the Sample Sequencing Engine + (SSE) interrupt sources to the SSE interrupt control functions. + */ +typedef enum +{ + PC0_FLAG0 = 0, + PC0_FLAG1 = 1, + PC0_FLAG2 = 2, + PC0_FLAG3 = 3, + PC1_FLAG0 = 4, + PC1_FLAG1 = 5, + PC1_FLAG2 = 6, + PC1_FLAG3 = 7, + PC2_FLAG0 = 8, + PC2_FLAG1 = 9, + PC2_FLAG2 = 10, + PC2_FLAG3 = 11, + ADC0_DATAVALID = 12, + ADC1_DATAVALID = 13, + ADC2_DATAVALID = 14, + ADC0_CALIBRATION_COMPLETE = 15, + ADC1_CALIBRATION_COMPLETE = 16, + ADC2_CALIBRATION_COMPLETE = 17, + ADC0_CALIBRATION_START = 18, + ADC1_CALIBRATION_START = 19, + ADC2_CALIBRATION_START = 20, + NB_OF_SSE_FLAG_IRQS = 21 +} sse_irq_id_t; + +/*-------------------------------------------------------------------------*//** + The ACE_enable_sse_irq() function enables the Sample Sequencing Engine (SSE) + interrupt source specified as parameter to generate interrupts. + + @param sse_irq_id + The sse_irq_id parameter identifies the SSE interrupt source controlled by + this function. + */ +void ACE_enable_sse_irq +( + sse_irq_id_t sse_irq_id +); + +/*-------------------------------------------------------------------------*//** + The ACE_disable_sse_irq() function disables the Sample Sequencing Engine + (SSE) interrupt source specified as parameter from generating interrupts. + + @param sse_irq_id + The sse_irq_id parameter identifies the SSE interrupt source controlled by + this function. + */ +void ACE_disable_sse_irq +( + sse_irq_id_t sse_irq_id +); + +/*-------------------------------------------------------------------------*//** + The ACE_clear_sse_irq() function clears the Sampling Sequencing Engine (SSE) + interrupt specified as parameter. + + @param sse_irq_id + The sse_irq_id parameter identifies the SSE interrupt source controlled by + this function. + */ +void ACE_clear_sse_irq +( + sse_irq_id_t sse_irq_id +); + +/** @} */ +/*============================================================================== + ============================ Comparators Control ============================== + =============================================================================*/ +/*=========================================================================*//** + @defgroup group5 Comparators Control + The following functions are used to control the analog comparators included + in the SmartFusion analog block. + The comparator configuration functions can be used to directly configure the + comparators. Their use is only required when the ACE is not configured using + the ACE configurator software tool. + The comparator interrupt control functions are used regardless of the way the + ACE was configured to enable, disable and clear interrupts generated when the + positive input of a comparator rises above or falls below the negative input. + @{ + *//*=========================================================================*/ + +/*-------------------------------------------------------------------------*//** + The comparator_id_t enumeration is used by the comparator control functions + to identify the analog comparators included in the SmartFusion analog block. + */ +typedef enum +{ + CMP0 = 0, /*!< Analog module 0, Quad 0, CMB comparator */ + CMP1 = 1, /*!< Analog module 0, Quad 0, TMB comparator */ + CMP2 = 2, /*!< Analog module 0, Quad 1, CMB comparator */ + CMP3 = 3, /*!< Analog module 0, Quad 1, TMB comparator */ + CMP4 = 4, /*!< Analog module 1, Quad 0, CMB comparator */ + CMP5 = 5, /*!< Analog module 1, Quad 0, TMB comparator */ + CMP6 = 6, /*!< Analog module 1, Quad 1, CMB comparator */ + CMP7 = 7, /*!< Analog module 1, Quad 1, TMB comparator */ + CMP8 = 8, /*!< Analog module 2, Quad 0, CMB comparator */ + CMP9 = 9, /*!< Analog module 2, Quad 0, TMB comparator */ + CMP10 = 10, /*!< Analog module 2, Quad 1, CMB comparator */ + CMP11 = 11, /*!< Analog module 2, Quad 1, TMB comparator */ + NB_OF_COMPARATORS = 12 +} comparator_id_t; + +/*-------------------------------------------------------------------------*//** + The comp_hysteresis_t enumeration is used by the ACE_set_comp_hysteresis() + function to set the hysteresis of the analog comparators included in the + SmartFusion analog block. This enumeration provides the allowed values of the + hysteresis parameter of the ACE_set_comp_hysteresis() function. + */ +typedef enum +{ + NO_HYSTERESIS = 0, + HYSTERESIS_10_MV = 1, + HYSTERESIS_30_MV = 2, + HYSTERESIS_100_MV = 3, + NB_OF_HYSTERESIS = 4 +} comp_hysteresis_t ; + +/*-------------------------------------------------------------------------*//** + The comp_reference_t enumeration is used by the ACE_set_comp_reference() + function to select the reference input of the odd numbered analog comparators + included in the SmartFusion analog block. This enumeration provides the allowed + values of the reference parameter of the ACE_set_comp_reference () function. + */ +typedef enum +{ + SDD0_COMP_REF = 0, + SDD1_COMP_REF = 1, + SDD2_COMP_REF = 2, + ADC_IN_COMP_REF = 3, + NB_OF_COMP_REF = 4 +} comp_reference_t; + +/*-------------------------------------------------------------------------*//** + The ACE_set_comp_reference() function is used to select the reference input + of a temperature monitor block comparator. The reference input of a temperature + monitor can be an ADC direct input or one of the SDD's output. + + @param comp_id + The comp_id parameter specifies the comparator for which to select the + reference input. Since only temperature monitor block comparators have a + selectable reference input, allowed values are: + - CMP1 + - CMP3 + - CMP5 + - CMP7 + - CMP9 + - CMP11 + + @param reference + The reference parameter specify the signal that will be used as reference + by the comparator. Allowed values are: + - SDD0_COMP_REF + - SDD1_COMP_REF + - SDD2_COMP_REF + - ADC_IN_COMP_REF + */ +void ACE_set_comp_reference +( + comparator_id_t comp_id, + comp_reference_t reference +); + +/*-------------------------------------------------------------------------*//** + The ACE_set_comp_hysteresis() function is used to set the hysteresis of a + comparator. There are four possible hystereris settings: no hysteresis, + +/-10mV, +/-30mV or +/-100mV. + + @param comp_id + The comp_id parameter specifies the comparator for which this function will + set the hyteresis. + + @param hysteresis + The hysteresis parameter specifies the hysteresis that will be applied to + the comparator's input. Allowed values are: + - NO_HYSTERESIS + - HYSTERESIS_10_MV + - HYSTERESIS_30_MV + - HYSTERESIS_100_MV + + */ +void ACE_set_comp_hysteresis +( + comparator_id_t comp_id, + comp_hysteresis_t hysteresis +); + +/*-------------------------------------------------------------------------*//** + The ACE_enable_comp() function is used to enable the comparator specified as + parameter. + + @param comp_id + The comp_id parameter specifies which comparator will be enabled by a call + to this function. + */ +void ACE_enable_comp +( + comparator_id_t comp_id +); + +/*-------------------------------------------------------------------------*//** + The ACE_disable_comp() function is used to disable the comparator specified as + parameter. + + @param comp_id + The comp_id parameter specifies which comparator will be disabled by a call + to this function. + */ +void ACE_disable_comp +( + comparator_id_t comp_id +); + +/*-------------------------------------------------------------------------*//** + The ACE_enable_comp_rise_irq() function is used to enable interrupts to be + generated when the positive input of the comparator specified as parameter + rises above the negative input of the comparator. + The function prototypes for the comparator rise interrupt service routines are: + - void ACE_Comp0_Rise_IRQHandler( void ); + - void ACE_Comp1_Rise_IRQHandler( void ); + - void ACE_Comp2_Rise_IRQHandler( void ); + - void ACE_Comp3_Rise_IRQHandler( void ); + - void ACE_Comp4_Rise_IRQHandler( void ); + - void ACE_Comp5_Rise_IRQHandler( void ); + - void ACE_Comp6_Rise_IRQHandler( void ); + - void ACE_Comp7_Rise_IRQHandler( void ); + - void ACE_Comp8_Rise_IRQHandler( void ); + - void ACE_Comp9_Rise_IRQHandler( void ); + - void ACE_Comp10_Rise_IRQHandler( void ); + - void ACE_Comp11_Rise_IRQHandler( void ); + + @param comp_id + The comp_id parameter specifies which comparator will be enabled to generate + rising interrupts. + */ +void ACE_enable_comp_rise_irq +( + comparator_id_t comp_id +); + +/*-------------------------------------------------------------------------*//** + The ACE_disable_comp_rise_irq() function is used to disable interrupts from + being generated when the positive input of the comparator specified as parameter + rises above the negative input of the comparator. + + @param comp_id + The comp_id parameter specifies which comparator will be disabled from + generating rising interrupts. + */ +void ACE_disable_comp_rise_irq +( + comparator_id_t comp_id +); + +/*-------------------------------------------------------------------------*//** + The ACE_clear_comp_rise_irq() function is used to clear rise interrupts. This + function is typically called as part of the rise interrupt service routine. + + @param comp_id + The comp_id parameter specifies the comparator for which to clear the rise + interrupt. + + Example: + @code + void ACE_Comp1_Rise_IRQHandler( void ) + { + process_rise_irq(); + ACE_clear_comp_rise_irq( CMP1 ); + NVIC_ClearPendingIRQ( ACE_Comp1_Rise_IRQn ); + } + @endcode + */ +void ACE_clear_comp_rise_irq +( + comparator_id_t comp_id +); + +/*-------------------------------------------------------------------------*//** + The ACE_enable_comp_fall_irq() function is used to enable interrupts to be + generated when the positive input of the comparator specified as parameter + falls below the negative input of the comparator. + The function prototypes for the comparator fall interrupt service routines are: + - void ACE_Comp0_Fall_IRQHandler( void ); + - void ACE_Comp1_Fall_IRQHandler( void ); + - void ACE_Comp2_Fall_IRQHandler( void ); + - void ACE_Comp3_Fall_IRQHandler( void ); + - void ACE_Comp4_Fall_IRQHandler( void ); + - void ACE_Comp5_Fall_IRQHandler( void ); + - void ACE_Comp6_Fall_IRQHandler( void ); + - void ACE_Comp7_Fall_IRQHandler( void ); + - void ACE_Comp8_Fall_IRQHandler( void ); + - void ACE_Comp9_Fall_IRQHandler( void ); + - void ACE_Comp10_Fall_IRQHandler( void ); + - void ACE_Comp11_Fall_IRQHandler( void ); + + @param comp_id + The comp_id parameter specifies which comparator will be enabled to generate + fall interrupts. + */ +void ACE_enable_comp_fall_irq +( + comparator_id_t comp_id +); + +/*-------------------------------------------------------------------------*//** + The ACE_disable_comp_fall_irq() function is used to disable interrupts from + being generated when the positive input of the comparator specified as parameter + falls below the negative input of the comparator. + + @param comp_id + The comp_id parameter specifies which comparator will be disabled from + generating fall interrupts. + */ +void ACE_disable_comp_fall_irq +( + comparator_id_t comp_id +); + +/*-------------------------------------------------------------------------*//** + The ACE_clear_comp_fall_irq() function is used to clear fall interrupts. This + function is typically called as part of the fall interrupt service routine. + + @param comp_id + The comp_id parameter specifies the comparator for which to clear the fall + interrupt. + + Example: + @code + void ACE_Comp1_Fall_IRQHandler( void ) + { + process_fall_irq(); + ACE_clear_comp_fall_irq( CMP1 ); + NVIC_ClearPendingIRQ( ACE_Comp1_Fall_IRQn ); + } + @endcode + */ +void ACE_clear_comp_fall_irq +( + comparator_id_t comp_id +); + +/*-------------------------------------------------------------------------*//** + The ACE_get_comp_status() function returns the current comparator interrupt + status. It returns a 32 bit value indicating which comparators experienced a + fall and/or rise event. These status bits can be cleared using the + ACE_clear_comp_rise_irq() and ACE_clear_comp_fall_irq() functions. + + @return + The return value is a 32 bit numnber where bits 0 to 11 indicate which + comparator experienced a fall event and bits 21 to 23 indicate which + comparator experienced a rise event. + */ +uint32_t ACE_get_comp_status( void ); + +/** @} */ + +/*============================================================================== + ========================== Controlling Thresholds ============================= + =============================================================================*/ +/*=========================================================================*//** + @defgroup group8 Controlling Flags Thresholds + The following functions are used to dynamically control Post Processing Engine + (PPE) flags threshholds. + @{ + *//*=========================================================================*/ + +/*-------------------------------------------------------------------------*//** + The ACE_is_hysteresis_flag() function indicates if an hysteresis is applied + to the analog input sample value when determining the state of the flag + identified as parameter. + + @param flag_handle + The flag_handle parameter identifies one of the flags generated based on the + value of an analog input channel. The available flag handle values can be + found in the ace_handles.h file located in the .\drivers_config\mss_ace + subdirectory. The flag handle value can also be retrieved through a call to + ACE_get_flag_handle() when the name of the flag is known, or by iterating + though all flags associated with an analog input channel using the + ACE_get_channel_first_flag() and ACE_get_channel_next_flag(). + + @return + This function returns the value one if a hysteresis is applied to the channel + sample values as part of determining the state of the flag identified as + parameter. It returns zero if no hysteresis is applied. + */ +uint32_t ACE_is_hysteresis_flag +( + ace_flag_handle_t flag_handle +); + +/*-------------------------------------------------------------------------*//** + The ACE_is_under_flag() function indicates whether a flag is triggered when the + monitored analog input falls below the flag's threshold level or above the + flag's threshold level. + + @param flag_handle + The flag_handle parameter identifies one of the flags generated based on the + value of an analog input channel. The available flag handle values can be + found in the ace_handles.h file located in the .\drivers_config\mss_ace + subdirectory. The flag handle value can also be retrieved through a call to + ACE_get_flag_handle() when the name of the flag is known, or by iterating + though all flags associated with an analog input channel using the + ACE_get_channel_first_flag() and ACE_get_channel_next_flag(). + + @return + This function returns the value one if the flag identified as parameter + triggers as a result of the monitored input falling below the flag's + threshold value. + It returns zero if the flag triggers as a result of the monitored input + exceeding the flag's threshold value. + */ +uint32_t ACE_is_under_flag +( + ace_flag_handle_t flag_handle +); + +/*-------------------------------------------------------------------------*//** + The ACE_set_flag_threshold() function is used to adjust the threshold for a + specific post processing engine generated flag. The flag is identified through + the name selected in the ACE configurator software tool. + This function will set a new flag’s threshold value while preserving the + hysteresis specified at configuration time or through a call to + ACE_set_flag_hysteresis(). For example, requesting a 1 volt threshold for an + over flag configured with a 100 millivolts hysteresis will result in the flag + being asserted when the voltage reaches 1.1 volts and deasserted when the + voltage falls below 0.9 volt. + + @param flag_handle + The flag_handle parameter identifies one of the flags generated based on the + value of an analog input channel. The available flag handle values can be + found in the ace_handles.h file located in the ./drivers_config/mss_ace + subdirectory. The flag handle value can also be retrieved through a call to + ACE_get_flag_handle() when the name of the flag is known, or by iterating + though all flags associated with an analog input channel using the + ACE_get_channel_first_flag() and ACE_get_channel_next_flag(). + + @param new_threshold + The new_threshold parameter specifies the new threshold level that must be + reached in order for the flag to be raised. The value of this parameter is + the sample value resulting from a post processing engine conversion of the + desired analog input threshold level. + + Example: + The function below sets the threshold of the flag specified as parameter to + 1 volt. + @code + void set_threshold_to_1V + ( + ace_flag_handle_t flag_handle + ) + { + uint16_t new_threshold; + ace_channel_handle_t channel_handle; + + channel_handle = ACE_get_flag_channel(flag_handle); + new_threshold = ACE_convert_from_mV(channel_handle, 1000); + ACE_set_flag_threshold(flag_handle, new_threshold); + } + @endcode + */ +void ACE_set_flag_threshold +( + ace_flag_handle_t flag_handle, + uint16_t new_threshold +); + +/*-------------------------------------------------------------------------*//** + The ACE_set_flag_hysteresis() function modifies the hysteresis applied to the + analog input channel sample values used to generate the flag specified as + parameter. + + @param flag_handle + The flag_handle parameter identifies one of the flags generated based on the + value of an analog input channel. The available flag handle values can be + found in the ace_handles.h file located in the .\drivers_config\mss_ace + subdirectory. The flag handle value can also be retrieved through a call to + ACE_get_flag_handle() when the name of the flag is known, or by iterating + though all flags associated with an analog input channel using the + ACE_get_channel_first_flag() and ACE_get_channel_next_flag(). + + @param adc_hysteresis + The adc_hysteresis parameter is the value to add and subtract to the + threshold value to obtain the hysteresis high and low limits triggering flag + assertion and deassertion. The adc_hysteresis parameter is a PPE conversion + result offset. + + Example + The example below demonstrates the use of the ACE_set_flag_hysteresis() + function to set a 100mV hysteresis on the OVER_1V flag of the VoltageMonitor + input channel. VoltageMonitor and OVER_1V are names selected in the ACE + configurator for one of the analog inputs and one of the flags associated + with that input. + The method used to compute the adc_hysteresis value will work for all + input types including ABPS inputs where zero Volts is not equivalent to a + PPE sample value of zero. + + @code + ace_channel_handle_t channel_handle; + ace_flag_handle_t flag_handle; + uint16_t adc_hysteresis; + uint16_t upper_limit; + uint16_t lower_limit; + + channel_handle = VoltageMonitor; + flag_handle = VoltageMonitor_OVER_1V; + + upper_limit = ACE_convert_from_mV(channel_handle, 100); + lower_limit = ACE_convert_from_mV(channel_handle, 0); + + if (upper_limit > lower_limit) + { + adc_hysteresis = upper_limit - lower_limit; + } + else + { + adc_hysteresis = lower_limit - upper_limit; + } + + ACE_set_flag_hysteresis(flag_handle, adc_hysteresis); + @endcode + */ +void +ACE_set_flag_hysteresis +( + ace_flag_handle_t flag_handle, + uint16_t adc_hysteresis +); + +/*-------------------------------------------------------------------------*//** + The ACE_set_flag_assertion() function sets the PPE sample value that must be + reached in order for the flag specified as parameter to become asserted. It is + used in conjunction with the ACE_set_flag_deassertion() function as an + alternative to the ACE_set_flag_threshold() and ACE_set_flag_hysteresis() + functions to set the hysteresis window of an hysteresis flag. + The ACE_set_flag_assertion() and ACE_set_flag_deassertion() functions are + intended to be used where the threshold value is not centered within the + hysteresis window. They allow specifying the actual threshold values at which + the flag will be asserted and deasserted. + + @param flag_handle + The flag_handle parameter identifies one of the flags generated based on the + value of an analog input channel. The available flag handle values can be + found in the ace_handles.h file located in the .\drivers_config\mss_ace + subdirectory. The flag handle value can also be retrieved through a call to + ACE_get_flag_handle() when the name of the flag is known, or by iterating + though all flags associated with an analog input channel using the + ACE_get_channel_first_flag() and ACE_get_channel_next_flag(). + + @param assertion_value + The assertion_value parameter is the Post Processing Engine sample value that + must be reached for the flag, identified through the flag_handle parameter, + to become asserted. The PPE sample value is always a 12 bits sample value + regardless of the configuration of the ADC used to sample the input channel. + */ +void ACE_set_flag_assertion +( + ace_flag_handle_t flag_handle, + uint16_t assertion_value +); + +/*-------------------------------------------------------------------------*//** + The ACE_set_flag_deassertion() function sets the PPE sample value that must be + reached in order for the flag specified as parameter to become deasserted. It + is used in conjunction with the ACE_set_flag_assertion() function as an + alternative to the ACE_set_flag_threshold() and ACE_set_flag_hysteresis() + functions to set the hysteresis window of an hysteresis flag. + The ACE_set_flag_assertion() and ACE_set_flag_deassertion() functions are + intended to be used where the threshold value is not centered within the + hysteresis window. They allow specifying the actual threshold values at which + the flag will be asserted and deasserted. + + @param flag_handle + The flag_handle parameter identifies one of the flags generated based on the + value of an analog input channel. The available flag handle values can be + found in the ace_handles.h file located in the .\drivers_config\mss_ace + subdirectory. The flag handle value can also be retrieved through a call to + ACE_get_flag_handle() when the name of the flag is known, or by iterating + though all flags associated with an analog input channel using the + ACE_get_channel_first_flag() and ACE_get_channel_next_flag(). + + @param assertion_value + The assertion_value parameter is the Post Processing Engine sample value + that must be reached for the flag, identified through the flag_handle + parameter, to become de-asserted. The PPE sample value is always a 12 bits + sample value regardless of the configuration of the ADC used to sample the + input channel. + */ +void ACE_set_flag_deassertion +( + ace_flag_handle_t flag_handle, + uint16_t assertion_value +); + +/*-------------------------------------------------------------------------*//** + The ACE_set_channel_hysteresis() function sets the hysteresis applied to + analog input channel sample values when generating flags. It sets the + hysteresis for all flags generated based on the value of the analog input + channel identified by the channel handle passed as first parameter. + + @param channel_handle + The channel_handle parameter identifies one of the analog input channels + monitored by the ACE. The available channel handle values can be found in + the ace_handles.h file located in the .\drivers_config\mss_ace subdirectory. + The channel handle value can also be retrieved through a call to + ACE_get_channel_handle() when the name of the channel is known, or by + iterating though all analog input channel using the ACE_get_first_channel() + and ACE_get_next_channel(). + + @param adc_hysteresis + The adc_hysteresis parameter is the value to add and subtract to the + threshold value to obtain the hysteresis high and low limits triggering flag + assertion and deassertion. The adc_hysteresis parameter is a PPE conversion + result offset. + */ +void +ACE_set_channel_hysteresis +( + ace_channel_handle_t channel_handle, + uint16_t adc_hysteresis +); + + +/** @} */ +/*-------------------------------------------------------------------------*//** + * + */ + +/*============================================================================== + ================================== Flags ====================================== + =============================================================================*/ +/*=========================================================================*//** + @defgroup group6 Post Processing Engine Flags + The following functions are used to control interrupts generated by the ACE's + Post Processing Engine (PPE) when monitored inputs rise above or fall below + thresholds specified in the ACE configurator software tool. + @{ + *//*=========================================================================*/ + + /*-------------------------------------------------------------------------*//** + These constant definitions are the return values of the ACE_get_flag_status() + function. They specify the status of the Post Processing Engine (PPE) flag. + */ +#define UNKNOWN_FLAG (int32_t)(-1) +#define FLAG_ASSERTED (int32_t)1 +#define FLAG_NOT_ASSERTED (int32_t)0 + +/*-------------------------------------------------------------------------*//** + This constant is returned by the ACE_get_flag_handle function when the driver + can’t find a valid handle for the Post Processing Engine (PPE) flag. + */ +#define INVALID_FLAG_HANDLE NB_OF_ACE_FLAG_HANDLES + +/*-------------------------------------------------------------------------*//** + The ACE_get_flag_handle() function returns the handle of the flag identified + by the flag name passed as parameter. The flag handle obtained through this + function is then used as parameter to other flag control functions to identify + which flag is to be controlled by the called function. + + @param p_sz_full_flag_name + The p_sz_full_flag_name parameter is a pointer to a zero-terminated string + holding the name of the flag as specified in the ACE configurator. The full + name of a flag contains both the name of the monitored input channel and the + name of the flag generated based the level of that input separated by ":". + For example, the full name for the flag called "CriticalOver" raised when + the input channel called "MainSupply" reaches a critical level would be + named "MainSupply:CriticalOver". + + @return + The ACE_get_flag_handle() returns the flag handle associated with the flag + name passed as parameter. It returns INVALID_FLAG_HANDLE when the flag name + is invalid and not recognized by the ACE driver. + */ +ace_flag_handle_t +ACE_get_flag_handle +( + const uint8_t * p_sz_full_flag_name +); + +/*-------------------------------------------------------------------------*//** + The ACE_get_flag_status() function returns the current status of the flag + specified as parameter. The flag is identified through the name specified in + the ACE configurator when the flag was created. + + @param flag_handle + The flag_handle parameter identifies one of the flags generated based on the + value of an analog input channel. The available flag handle values can be + found in the ace_handles.h file located in the .\drivers_config\mss_ace + subdirectory. The flag handle value can also be retrieved through a call to + ACE_get_flag_handle() when the name of the flag is known, or by iterating + though all flags associated with an analog input channel using the + ACE_get_channel_first_flag() and ACE_get_channel_next_flag(). + + @return + The ACE_get_flag_status() function returns one of the following values + depending on the current status of the flag: + - FLAG_ASSERTED if the flag is raised/asserted. + - FLAG_NOT_ASSERTED if the flag is not asserted. + - UNKNOWN_FLAG if the flag name is not recognized by the driver. +*/ +int32_t +ACE_get_flag_status +( + ace_flag_handle_t flag_handle +); + +/*-------------------------------------------------------------------------*//** + The ACE_enable_channel_flags_irq() function enables all flags generated based + on the value of the analog input channel passed as parameter to generate + interrupts. Flags used to detect that thresholds are crossed by the value + sampled on the analog input channel identified as parameter are enabled to + generate interrupts by this function. It enables flag interrupts both at the + ACE PEE flag and Cortex-M3 interrupt controller levels. + + @param channel_handle + The channel_handle parameter identifies one of the analog input channels + monitored by the ACE. The available channel handle values can be found in the + ace_handles.h file located in the ./drivers_config/mss_ace subdirectory. The + channel handle value can also be retrieved through a call to + ACE_get_channel_handle() when the name of the channel is known, or by + iterating though all analog input channel using the ACE_get_first_channel() + and ACE_get_next_channel(). + */ +void ACE_enable_channel_flags_irq +( + ace_channel_handle_t channel_handle +); + +/*-------------------------------------------------------------------------*//** + The ACE_disable_channel_flags_irq() function disables all flags generated + based on the value of the analog input channel passed as parameter to generate + interrupts. Flags used to detect that thresholds are crossed by the value + sampled on the analog input channel identified as parameter are disabled from + generating interrupts by this function. The interrupt is only disabled at the + ACE PPE flag level in order to avoid disabling other cahnnel's flag interrupts + which may happen to use the same ACE threshold interrupt line. + + @param channel_handle + The channel_handle parameter identifies one of the analog input channels + monitored by the ACE. The available channel handle values can be found in the + ace_handles.h file located in the ./drivers_config/mss_ace subdirectory. The + channel handle value can also be retrieved through a call to + ACE_get_channel_handle() when the name of the channel is known, or by + iterating though all analog input channel using the ACE_get_first_channel() + and ACE_get_next_channel(). + */ +void ACE_disable_channel_flags_irq +( + ace_channel_handle_t channel_handle +); + +/*-------------------------------------------------------------------------*//** + The ACE_clear_channel_flags_irq() function clears all interrupts generated by + flags associated with the analog input channel passed as parameter. Interrupt + generated by flags used to detect that thresholds are crossed by the value + sampled on the analog input channel identified as parameter are cleared by + this function. This function would typically be used before enabling the flag + interrupts in order to ignore past events. + + @param channel_handle + The channel_handle parameter identifies one of the analog input channels + monitored by the ACE. The available channel handle values can be found in the + ace_handles.h file located in the ./drivers_config/mss_ace subdirectory. The + channel handle value can also be retrieved through a call to + ACE_get_channel_handle() when the name of the channel is known, or by + iterating though all analog input channel using the ACE_get_first_channel() + and ACE_get_next_channel(). + */ +void ACE_clear_channel_flags_irq +( + ace_channel_handle_t channel_handle +); + +/*-------------------------------------------------------------------------*//** + The ACE_enable_flag_irq() function enables the ACE post processing engine (PPE) + generated flags specified as parameter to interrupt the Cortex-M3 processor. + It enables flag interrupts both at the ACE PPE flag and Cortex-M3 interrupt + controller levels. + + @param flag_handle + The flag_handle parameter identifies one of the flags generated based on the + value of an analog input channel. The available flag handle values can be + found in the ace_handles.h file located in the .\drivers_config\mss_ace + subdirectory. The flag handle value can also be retrieved through a call to + ACE_get_flag_handle() when the name of the flag is known, or by iterating + though all flags associated with an analog input channel using the + ACE_get_channel_first_flag() and ACE_get_channel_next_flag(). + */ +void ACE_enable_flag_irq +( + ace_flag_handle_t flag_handle +); + +/*-------------------------------------------------------------------------*//** + The ACE_disable_flag_irq() function disables ACE post processing engine (PPE) + generated flags from interrupting the Cortex-M3. The interrupt is only + disabled at the ACE PPE flag level in order to avoid disabling other flags + interrupts which may happen to use the same ACE threshold interrupt line. + + @param flag_handle + The flag_handle parameter identifies one of the flags generated based on the + value of an analog input channel. The available flag handle values can be + found in the ace_handles.h file located in the .\drivers_config\mss_ace + subdirectory. The flag handle value can also be retrieved through a call to + ACE_get_flag_handle() when the name of the flag is known, or by iterating + though all flags associated with an analog input channel using the + ACE_get_channel_first_flag() and ACE_get_channel_next_flag(). + */ +void ACE_disable_flag_irq +( + ace_flag_handle_t flag_handle +); + +/*-------------------------------------------------------------------------*//** + The ACE_clear_flag_irq() function clears the interrupt for the flag specified + as parameter. This function would typically be used before enabling the flag + interrupt in order to ignore past events. + + @param flag_handle + The flag_handle parameter identifies one of the flags generated based on the + value of an analog input channel. The available flag handle values can be + found in the ace_handles.h file located in the .\drivers_config\mss_ace + subdirectory. The flag handle value can also be retrieved through a call to + ACE_get_flag_handle() when the name of the flag is known, or by iterating + though all flags associated with an analog input channel using the + ACE_get_channel_first_flag() and ACE_get_channel_next_flag(). + */ +void ACE_clear_flag_irq +( + ace_flag_handle_t flag_handle +); + +/*-------------------------------------------------------------------------*//** + The ACE_get_flag_name() function returns the name of the flag identified by + the flag handle passed as parameter. + + @param flag_handle + The flag_handle parameter identifies one of the flags generated based on the + value of an analog input channel. The available flag handle values can be + found in the ace_handles.h file located in the .\drivers_config\mss_ace + subdirectory. The flag handle value can also be retrieved through a call to + ACE_get_flag_handle() when the name of the flag is known, or by iterating + though all flags associated with an analog input channel using the + ACE_get_channel_first_flag() and ACE_get_channel_next_flag(). + + @return + The ACE_get_flag_name() function returns a pointer to a zero-terminated + string containing the name of the flag identified by the flag handle passed + as parameter. It returns 0 if the flag handle passed as parameter is invalid. + */ +const uint8_t * +ACE_get_flag_name +( + ace_flag_handle_t flag_handle +); + +/*-------------------------------------------------------------------------*//** + The ACE_get_flag_channel() function returns the handle of the channel + monitored in order to generate the flag identified by the flag handle passed + as parameter. + + @param flag_handle + The flag_handle parameter identifies one of the flags generated based on the + value of an analog input channel. The available flag handle values can be + found in the ace_handles.h file located in the .\drivers_config\mss_ace + subdirectory. The flag handle value can also be retrieved through a call to + ACE_get_flag_handle() when the name of the flag is known, or by iterating + though all flags associated with an analog input channel using the + ACE_get_channel_first_flag() and ACE_get_channel_next_flag(). + + @return + The ACE_get_flag_channel() function returns a channel handle identifying the + analog input channel monitored by the flag passed as parameter. + */ +ace_channel_handle_t +ACE_get_flag_channel +( + ace_flag_handle_t flag_handle +); + +/*-------------------------------------------------------------------------*//** + The ACE_get_channel_flag_count() function returns the total number of flags + associated with the input channel specified by the channel_handle parameter. + It indicates how many flags are generated based on the value of the specified + analog input channel. + + @param channel_handle + The channel_handle parameter identifies one of the analog input channels + monitored by the ACE. The available channel handle values can be found in + the ace_handles.h file located in the .\drivers_config\mss_ace subdirectory. + The channel handle value can also be retrieved through a call to + ACE_get_channel_handle() when the name of the channel is known, or by + iterating though all analog input channel using the ACE_get_first_channel() + and ACE_get_next_channel(). + + @return + The ACE_get_channel_flag_count() function returns the total number of flags + that are generated based on the value of the specified analog input channel. + The ACE_get_channel_flag_count() function returns 0 if no input channels were + configured. + + Example + @code + uint32_t inc; + uint32_t nb_of_flags; + uint16_t flag_iterator; + ace_flag_handle_t current_flag; + ace_channel_handle_t channel_handle; + + nb_of_flags = ACE_get_channel_flag_count(channel_handle); + current_flag = ACE_get_channel_first_flag(channel_handle, &flag_iterator); + + for (inc = 0; inc < nb_of_flags; ++inc) + { + current_flag = ACE_get_channel_next_flag(channel_handle, &flag_iterator); + display_flag_properties(current_flag); + } + @endcode + */ +uint32_t +ACE_get_channel_flag_count +( + ace_channel_handle_t channel_handle +); + +/*-------------------------------------------------------------------------*//** + The ACE_get_channel_first_flag() function retrieves the handle of the first + flag associated with the analog input channel identified by the channel handle + passed as parameter. It also initialises the value of the iterator variable + pointed to by the second function parameter. The iterator can be used + subsequently as a parameter to the ACE_get_channel_next_flag() function to + iterate through all flags associated with the analog input channel. + + @param channel_handle + The channel_handle parameter identifies one of the analog input channels + monitored by the ACE. The available channel handle values can be found in the + ace_handles.h file located in the ./drivers_config/mss_ace subdirectory. + The channel handle value can also be retrieved through a call to + ACE_get_channel_handle() when the name of the channel is known, or by + iterating though all analog input channel using the ACE_get_first_channel() + and ACE_get_next_channel(). + + @param iterator + The iterator parameter is a pointer to a uint16_t iterator variable. The + value of the iterator variable will be set by the ACE_get_channel_first_flag() + functions so that it can be used in subsequent calls to + ACE_get_channel_next_flag() to keep track of the current location in the + list of flags associated with the analog input channel. + + @return + The ACE_get_channel_first_flag() function returns a flag handle identifying + one of the flags generated based on the value of the analog input channel + identified by the channel_handle parameter. It returns INVALID_FLAG_HANDLE + if no flags are generated based on the analog input channel input or if the + channel handle is invalid. + + Example + @code + uint32_t inc; + uint32_t nb_of_flags; + uint16_t flag_iterator; + ace_flag_handle_t current_flag; + ace_channel_handle_t channel_handle; + + nb_of_flags = ACE_get_channel_flag_count(channel_handle); + current_flag = ACE_get_channel_first_flag(channel_handle, &flag_iterator); + + for (inc = 0; inc < nb_of_flags; ++inc) + { + current_flag = ACE_get_channel_next_flag(channel_handle, &flag_iterator); + display_flag_properties(current_flag); + } + @endcode + */ +ace_flag_handle_t +ACE_get_channel_first_flag +( + ace_channel_handle_t channel_handle, + uint16_t * iterator +); + +/*-------------------------------------------------------------------------*//** + The ACE_get_channel_next_flag() function retrieves the handle of a flag + associated with the analog input channel identified by the channel handle + passed as parameter. The retrieved flag handle is the next one in the driver's + internal flag list based on the iterator parameter. + + @param channel_handle + The channel_handle parameter identifies one of the analog input channels + monitored by the ACE. The available channel handle values can be found in the + ace_handles.h file located in the .\drivers_config\mss_ace subdirectory. + The channel handle value can also be retrieved through a call to + ACE_get_channel_handle() when the name of the channel is known, or by + iterating though all analog input channel using the ACE_get_first_channel() + and ACE_get_next_channel(). + + @param iterator + The iterator parameter is a pointer to a uint16_t iterator variable. The value + of the iterator variable will be set by the ACE_get_channel_first_flag() + functions so that it can be used in subsequent calls to + ACE_get_channel_next_flag() to keep track of the current location in the list + of flags associated with the analog input channel. + + Example + @code + uint32_t inc; + uint32_t nb_of_flags; + uint16_t flag_iterator; + ace_flag_handle_t current_flag; + ace_channel_handle_t channel_handle; + + nb_of_flags = ACE_get_channel_flag_count(channel_handle); + current_flag = ACE_get_channel_first_flag(channel_handle, &flag_iterator); + + for (inc = 0; inc < nb_of_flags; ++inc) + { + current_flag = ACE_get_channel_next_flag(channel_handle, &flag_iterator); + display_flag_properties(current_flag); + } + @endcode + */ +ace_flag_handle_t +ACE_get_channel_next_flag +( + ace_channel_handle_t channel_handle, + uint16_t * iterator +); + +/*-------------------------------------------------------------------------*//** + This defines the function prototype that must be followed by MSS ACE Post + Processing Engine (PPE) flag handler functions. These functions are registered + with the ACE driver and associated with a particular flag through the + ACE_register_flag_isr() function. The ACE driver will call the flag handler + function when the associated flag is raised. + + Declaring and Implementing PPE Flag Handler Functions + PPE flag handler functions should follow the following prototype: + void my_flag_handler ( ace_flag_handle_t flag_handle ); + The actual name of the PPE flag handler is unimportant. You can use any name of + your choice for the PPE flag handler. + The flag_handle parameter passes the handle of the raised flag to the flag + handler function. + */ +typedef void (*flag_isr_t)( ace_flag_handle_t flag_handle ); + +/*-------------------------------------------------------------------------*//** + The ACE_register_flag_isr() function is used to register a handler function + with the ACE driver. The registered function will be called by the ACE driver + when the associated flag is raised by the ACE post processing engine. + + @param flag_handle + The flag_handle parameter identifies one of the flags generated based on the + value of an analog input channel. The available flag handle values can be + found in the ace_handles.h file located in the .\drivers_config\mss_ace + subdirectory. The flag handle value can also be retrieved through a call to + ACE_get_flag_handle() when the name of the flag is known, or by iterating + though all flags associated with an analog input channel using the + ACE_get_channel_first_flag() and ACE_get_channel_next_flag(). + + @param flag_isr + The flag_isr parameter is a pointer to a flag handler function with the + following prototype: + void handler_function_name(ace_flag_handle_t flag_handle) + The flag handler function is called by the ACE driver as part of the relevant + post processing engine flag interrupt service routine. It does not need to + handle flag interrupt clearing as this is done by the ACE driver. + + + @code + void my_critical_handler( void ); + + void system_init( void ) + { + ace_flag_handle_t flag_handle; + + flag_handle = ACE_get_flag_handle( "MainSupply:CriticalLevel" ); + ACE_register_flag_isr( flag_handle, my_critical_handler ); + ACE_enable_flag_irq( flag_handle ); + } + + void my_critical_handler( ace_flag_handle_t flag_handle ) + { + panic( flag_handle ); + } + + @endcode + */ +void ACE_register_flag_isr +( + ace_flag_handle_t flag_handle, + flag_isr_t flag_isr +); + +/*-------------------------------------------------------------------------*//** + This defines the function prototype that must be followed by MSS ACE Post + Processing Engine (PPE) channel flag handler functions. These functions are + registered with the ACE driver and associated with a particular ADC input + channel through the ACE_register_channel_flags_isr() function. The ACE driver + will call the channel flags handler function when one of the flags for the + associated ADC input channel is raised. + + Declaring and Implementing PPE Channel Flag Handler Functions + PPE channel flag handler functions should follow the following prototype: + void my_channel_flag_handler ( ace_flag_handle_t flag_handle ); + The actual name of the PPE channel flag handler is unimportant. You can use + any name of your choice for the PPE channel flag handler. The flag_handle + parameter passes the handle of the raised flag to the channel flag handler + function. + */ +typedef void (*channel_flag_isr_t)( ace_flag_handle_t flag_handle ); + +/*-------------------------------------------------------------------------*//** + The ACE_register_channel_flags_isr() function is used to register a flag + interrupt handler function with the ACE driver. The registered interrupt + handler will be called by the ACE driver when one of the flag generated based + on the value of the analog input channel identified by the channel handle + passed as parameter is asserted. + + @param channel_handle + The channel_handle parameter identifies one of the analog input channels + monitored by the ACE. The available channel handle values can be found in the + ace_handles.h file located in the ./drivers_config/mss_ace subdirectory. The + channel handle value can also be retrieved through a call to + ACE_get_channel_handle() when the name of the channel is known, or by + iterating though all analog input channel using the ACE_get_first_channel() + and ACE_get_next_channel(). + + @param channel_flag_isr + The channel_flag_isr parameter is pointer to a function taking a flag handle + as parameter. + void handler_function_name(ace_flag_handle_t flag_handle) + The flag handler function is called by the ACE driver as part of the relevant + post processing engine flag interrupt service routine. It does not need to + handle flag interrupt clearing as this is done by the ACE driver. + + Example + The example below demonstrates the use of the ACE_register_channel_flags_isr() + function in a system where the ACE is configured to have an analog input + channels named "MainSupply" with one flag named "Critical" generated based + on the value of "MainSupply" channel. The names "MainSupply" and "Critical" + were user selected in the ACE configurator. + @code + void main_supply_handler (ace_flag_handle_t flag_handle); + + void system_init(void) + { + ACE_register_channel_flag_isr(MainSupply, main_supply_handler); + ACE_enable_channel_flags_irq(MainSupply); + } + + void main_supply_handler (ace_flag_handle_t flag_handle) + { + if (MainSupply_Critical == flag_handle) + { + panic(flag_handle); + } + } + + @endcode +*/ +void ACE_register_channel_flags_isr +( + ace_channel_handle_t channel_handle, + channel_flag_isr_t channel_flag_isr +); + +/*-------------------------------------------------------------------------*//** + This defines the function prototype that must be followed by MSS ACE Post + Processing Engine (PPE) global flag handler functions. These functions are + registered with the ACE driver through the ACE_register_global_flags_isr() + function. The ACE driver will call the global flags handler function when any + flag for any ADC input channel is raised. + + Declaring and Implementing Global Flag Handler Functions + PPE global flag handler functions should follow the following prototype: + void my_global_flag_handler( + ace_flag_handle_t flag_handle, + ace_channel_handle_t channel_handle + ); + The actual name of the PPE global flag handler is unimportant. You can use any + name of your choice for the PPE global flag handler. The flag_handle parameter + passes the handle of the raised flag to the global flag handler function. The + channel_handle parameter passes the handle of the channel for which the flag + was raised to the global flag handler function. + + */ +typedef void (*global_flag_isr_t)( ace_flag_handle_t flag_handle, ace_channel_handle_t channel_handle ); + +/*-------------------------------------------------------------------------*//** + The ACE_register_global_flags_isr() function is used to register a global + flag handler function with the ACE driver. The registered global handler will + be called when any flag interrupt is generated. + + @param global_flag_isr + The global_flag_isr parameter is a pointer to a function taking a flag + handle and channel handle as parameter. + */ +void ACE_register_global_flags_isr +( + global_flag_isr_t global_flag_isr +); + +/** @} */ + +/*=========================================================================*//** + @defgroup group11 Conversion Functions + The following functions are used to convert an ADC sample value to a real + world unit. + @{ + *//*=========================================================================*/ + +/*-------------------------------------------------------------------------*//** + The ACE_convert_adc_input_to_mV() function converts an ADC sample value into + the value in millivolts of the voltage seen at ADC input. It does not account + for prescaling taking place before the ADC hardware input. + + @param channel_handle + The channel_handle parameter identifies one of the analog input channels + monitored by the ACE. The available channel handle values can be found in the + ace_handles.h file located in the ./drivers_config/mss_ace subdirectory. The + channel handle value can also be retrieved through a call to + ACE_get_channel_handle() when the name of the channel is known, or by + iterating though all analog input channel using the ACE_get_first_channel() + and ACE_get_next_channel(). + + @param sample_value + The sample_value parameter is the result of an analog to digital conversion. + + @return + The ACE_convert_adc_input_to_mV() returns the number of millivolts derived + from the ADC sample value passed as parameter. + */ +uint32_t ACE_convert_adc_input_to_mV +( + ace_channel_handle_t channel_handle, + uint16_t sample_value +); + +/*-------------------------------------------------------------------------*//** + The ACE_convert_to_mV() function converts a PPE sample value into milli-Volts. + It handles prescaling adjusments based on ACE configuration for ABPS inputs. + + @param channel_handle + The channel_handle parameter identifies one of the analog input channels + monitored by the ACE. The available channel handle values can be found in the + ace_handles.h file located in the ./drivers_config/mss_ace subdirectory. The + channel handle value can also be retrieved through a call to + ACE_get_channel_handle() when the name of the channel is known, or by + iterating though all analog input channel using the ACE_get_first_channel() + and ACE_get_next_channel(). + + @param sample_value + The sample_value parameter is the result of an analog to digital conversion. + + @return + The ACE_convert_to_mV() returns the number of millivolts derived from the + PPE sample value passed as parameter. The returned value can be either + positive or negative since prescaling is accounted for in the conversion. + */ +int32_t ACE_convert_to_mV +( + ace_channel_handle_t channel_handle, + uint16_t sample_value +); + +/*-------------------------------------------------------------------------*//** + The ACE_convert_to_mA() function converts a PPE sample value into milli-Amps. + The result of the conversion is only meaningful if the PPE sample value + results from the conversion of a current monitor input. + + @param channel_handle + The channel_handle parameter identifies one of the analog input channels + monitored by the ACE. The available channel handle values can be found in the + ace_handles.h file located in the ./drivers_config/mss_ace subdirectory. The + channel handle value can also be retrieved through a call to + ACE_get_channel_handle() when the name of the channel is known, or by + iterating though all analog input channel using the ACE_get_first_channel() + and ACE_get_next_channel(). + + @param sample_value + The sample_value parameter is the result of an analog to digital conversion + of the voltage generated by a current monitor analog block. + + @return + The ACE_convert_to_mA() returns the number of milliamps derived from the + PPE sample value passed as parameter. + */ +uint32_t ACE_convert_to_mA +( + ace_channel_handle_t channel_handle, + uint16_t sample_value +); + +/*-------------------------------------------------------------------------*//** + The ACE_convert_to_Kelvin() function converts a PPE sample value into degrees + Kelvin. The result of the conversion is only meaningful if the PPE sample value + results from the conversion of a temperature monitor input. + + @param channel_handle + The channel_handle parameter identifies one of the analog input channels + monitored by the ACE. The available channel handle values can be found in the + ace_handles.h file located in the ./drivers_config/mss_ace subdirectory. The + channel handle value can also be retrieved through a call to + ACE_get_channel_handle() when the name of the channel is known, or by + iterating though all analog input channel using the ACE_get_first_channel() + and ACE_get_next_channel(). + + @param sample_value + The sample_value parameter is the result of an analog to digital conversion + of the voltage generated by a temperature monitor analog block. + + @return + The ACE_convert_to_Kelvin() returns the number of degrees Kelvin derived + from the PPE sample value passed as parameter. + */ +uint32_t ACE_convert_to_Kelvin +( + ace_channel_handle_t channel_handle, + uint16_t sample_value +); + +/*-------------------------------------------------------------------------*//** + The ACE_convert_to_Celsius() function converts a PPE sample value into tenths + of degrees Celsius. The result of the conversion is only meaningful if the PPE + sample value results from the conversion of a temperature monitor input. + + @param channel_handle + The channel_handle parameter identifies one of the analog input channels + monitored by the ACE. The available channel handle values can be found in the + ace_handles.h file located in the ./drivers_config/mss_ace subdirectory. The + channel handle value can also be retrieved through a call to + ACE_get_channel_handle() when the name of the channel is known, or by + iterating though all analog input channel using the ACE_get_first_channel() + and ACE_get_next_channel(). + + @param sample_value + The sample_value parameter is the result of an analog to digital conversion + of the voltage generated by a temperature monitor analog block. + + @return + The ACE_convert_to_Celsius() returns the number of tenths of degrees Celsius + derived from the PPE sample value passed as parameter. + */ +int32_t ACE_convert_to_Celsius +( + ace_channel_handle_t channel_handle, + uint16_t sample_value +); + +/*-------------------------------------------------------------------------*//** + The ACE_convert_to_Fahrenheit() function converts a PPE sample value into + degrees Fahrenheit. The result of the conversion is only meaningful if the PPE + sample value results from the conversion of a temperature monitor input. + + @param channel_handle + The channel_handle parameter identifies one of the analog input channels + monitored by the ACE. The available channel handle values can be found in the + ace_handles.h file located in the ./drivers_config/mss_ace subdirectory. The + channel handle value can also be retrieved through a call to + ACE_get_channel_handle() when the name of the channel is known, or by + iterating though all analog input channel using the ACE_get_first_channel() + and ACE_get_next_channel(). + + @param sample_value + The sample_value parameter is the result of an analog to digital conversion + of the voltage generated by a temperature monitor analog block. + + @return + The ACE_convert_to_Fahrenheit() returns the number of degrees Fahrenheit + derived from the PPE sample value passed as parameter. + */ +int32_t ACE_convert_to_Fahrenheit +( + ace_channel_handle_t channel_handle, + uint16_t sample_value +); + +/*-------------------------------------------------------------------------*//** + The ACE_convert_mV_to_adc_value() function converts a voltage value given in + milli-Volts into the ADC sample value that would result from sampling this + voltage value on the analog input channel specified as parameter. + This function is intended for use when directly controlling the ADC, not when + using samples read from the PPE. It does not account for prescaling taking + place before the ADC hardware input. + + @param channel_handle + The channel_handle parameter identifies one of the analog input channels + monitored by the ACE. The available channel handle values can be found in the + ace_handles.h file located in the ./drivers_config/mss_ace subdirectory. The + channel handle value can also be retrieved through a call to + ACE_get_channel_handle() when the name of the channel is known, or by + iterating though all analog input channel using the ACE_get_first_channel() + and ACE_get_next_channel(). + + @param voltage + The voltage parameter is the milli-Volts voltage value for which we want this + function to return the associated ADC sample result value. + + @return + The ACE_convert_mV_to_adc_value() returns the ADC sample value that would be + produced if the analog input channel identified by channel_handle was set to + the voltage value passed as second parameter. + */ +uint16_t ACE_convert_mV_to_adc_value +( + ace_channel_handle_t channel_handle, + uint32_t voltage +); + +/*-------------------------------------------------------------------------*//** + The ACE_convert_from_mV() function converts a voltage value given in + milli-Volts into the PPE sample value that would result from sampling this + voltage value on the analog input channel specified as parameter. + This function handles prescaling adjusments based on ACE configuration for + ABPS inputs. + + @param channel_handle + The channel_handle parameter identifies one of the analog input channels + monitored by the ACE. The available channel handle values can be found in the + ace_handles.h file located in the ./drivers_config/mss_ace subdirectory. The + channel handle value can also be retrieved through a call to + ACE_get_channel_handle() when the name of the channel is known, or by + iterating though all analog input channel using the ACE_get_first_channel() + and ACE_get_next_channel(). + + @param voltage + The voltage parameter is the milli-Volts voltage value for which we want this + function to return the associated PPE sample result value. + + @return + The ACE_convert_from_mV() returns the PPE sample value that would be produced + if the analog input channel identified by channel_handle was set to the + voltage value passed as second parameter. + */ +uint16_t ACE_convert_from_mV +( + ace_channel_handle_t channel_handle, + int32_t voltage +); + +/*-------------------------------------------------------------------------*//** + The ACE_convert_from_mA() function converts a current value given in + milli-Amps into the PPE sample value that would result from sampling this + current value on the analog input channel specified as parameter. + The result of the conversion is only meaningful if the analog input channel + specified as parameter is configured as a current monitoring channel. + + @param channel_handle + The channel_handle parameter identifies one of the analog input channels + monitored by the ACE. The available channel handle values can be found in the + ace_handles.h file located in the ./drivers_config/mss_ace subdirectory. The + channel handle value can also be retrieved through a call to + ACE_get_channel_handle() when the name of the channel is known, or by + iterating though all analog input channel using the ACE_get_first_channel() + and ACE_get_next_channel(). + + @param current + The current parameter is the milli-Amps current value for which we want this + function to return the associated PPE sample result value. + + @return + The ACE_convert_from_mA() returns the PPE sample value that would be produced + if the analog input channel identified by channel_handle was set to the + current value passed as second parameter. + */ +uint16_t ACE_convert_from_mA +( + ace_channel_handle_t channel_handle, + uint32_t current +); + +/*-------------------------------------------------------------------------*//** + The ACE_convert_from_Kelvin() function converts a temperature value given in + degrees Kelvin into the PPE sample value that would result from sampling this + temperature value on the analog input channel specified as parameter. + The result of the conversion is only meaningful if the analog input channel + specified as parameter is configured as a temperature monitoring channel. + + @param channel_handle + The channel_handle parameter identifies one of the analog input channels + monitored by the ACE. The available channel handle values can be found in the + ace_handles.h file located in the ./drivers_config/mss_ace subdirectory. The + channel handle value can also be retrieved through a call to + ACE_get_channel_handle() when the name of the channel is known, or by + iterating though all analog input channel using the ACE_get_first_channel() + and ACE_get_next_channel(). + + @param temperature + The temperature parameter is the degrees Kelvin temperature value for which + we want this function to return the associated PPE sample result value. + + @return + The ACE_convert_from_Kelvin() returns the PPE sample value that would be + produced if the analog input channel identified by channel_handle was set to + the temperature value passed as second parameter. + */ +uint16_t ACE_convert_from_Kelvin +( + ace_channel_handle_t channel_handle, + uint32_t temperature +); + +/*-------------------------------------------------------------------------*//** + The ACE_convert_from_Celsius() function converts a temperature value given in + degrees Celsius into the PPE sample value that would result from sampling this + temperature value on the analog input channel specified as parameter. + The result of the conversion is only meaningful if the analog input channel + specified as parameter is configured as a temperature monitoring channel. + + @param channel_handle + The channel_handle parameter identifies one of the analog input channels + monitored by the ACE. The available channel handle values can be found in the + ace_handles.h file located in the ./drivers_config/mss_ace subdirectory. The + channel handle value can also be retrieved through a call to + ACE_get_channel_handle() when the name of the channel is known, or by + iterating though all analog input channel using the ACE_get_first_channel() + and ACE_get_next_channel(). + + @param temperature + The temperature parameter is the degrees Celsius temperature value for which + we want this function to return the associated PPE sample result value. + + @return + The ACE_convert_from_Celsius() returns the PPE sample value that would be + produced if the analog input channel identified by channel_handle was set to + the temperature value passed as second parameter. + */ +uint16_t ACE_convert_from_Celsius +( + ace_channel_handle_t channel_handle, + int32_t temperature +); + +/*-------------------------------------------------------------------------*//** + The ACE_convert_from_Fahrenheit() function converts a temperature value given + in degrees Fahrenheit into the PPE sample value that would result from sampling + this temperature value on the analog input channel specified as parameter. + The result of the conversion is only meaningful if the analog input channel + specified as parameter is configured as a temperature monitoring channel. + + @param channel_handle + The channel_handle parameter identifies one of the analog input channels + monitored by the ACE. The available channel handle values can be found in the + ace_handles.h file located in the ./drivers_config/mss_ace subdirectory. The + channel handle value can also be retrieved through a call to + ACE_get_channel_handle() when the name of the channel is known, or by + iterating though all analog input channel using the ACE_get_first_channel() + and ACE_get_next_channel(). + + @param temperature + The temperature parameter is the degrees Fahrenheit temperature value for + which we want this function to return the associated PPE sample result value. + + @return + The ACE_convert_from_Fahrenheit() returns the PPE sample value that would be + produced if the analog input channel identified by channel_handle was set to + the temperature value passed as second parameter. + */ +uint16_t ACE_convert_from_Fahrenheit +( + ace_channel_handle_t channel_handle, + int32_t temperature +); + +/*-------------------------------------------------------------------------*//** + The ACE_translate_pdma_value() function translates PDMA sampling values, + received from the ACE via PDMA transfers, into input channel ID and PPE + sample value. + The PDMA sampling values are generated by the ACE as a result of selecting + "Send result to DMA" in the ACE configurator analog input configuration. The + PDMA sampling values can be either raw ADC values, filtered values or the + result of a linear transformation. + The PDMA sampling values are obtained by configuring the PDMA controller to + transfer data from the ACE into a memory buffer. The ACE_translate_pdma_value() + function is used to interpret the content of that memory buffer. + + Please note that the translation of PDMA data containing raw ADC values from + ABPS inputs will result in sample values with an unexpected polarity. + The returned sample value will have the opposite polarity to the actual analog + value seen on the ABPS input. This is due to the internal characteristics of + the analog front end that are normally hidden by the PPE processing of ADC raw + samples. The translation of raw ADC values from analog inputs other than ABPS + inputs will result in correct sample values. + + @param pdma_value + The pdma_value parameter is a 32-bit value received from the ACE through a + peripheral DMA transfer. + + @param channel_id + The channel_id parameter is a pointer to an ADC channel ID variable. It is + used to return the ID of the ADC channel from which the PPE sample value + was generated from. This parameter can be set to zero if retrieving the + channel ID is not required. + + @return + The ACE_translate_pdma_value() returns the PPE sample value extracted from + the PDMA sampling value. + + Example: + @code + uint16_t ppe_value; + uint16_t pdma_value; + adc_channel_id_t channel_id; + ace_channel_handle_t channel_handle; + + pdma_value = get_next_pdma_ace_sample(); + ppe_value = ACE_translate_pdma_value(pdma_value, &channel_id); + channel_handle = ACE_get_input_channel_handle(channel_id); + if (channel_handle != INVALID_CHANNEL_HANDLE) + { + display_value(channel_handle, ppe_value); + } + @endcode + + */ +uint16_t ACE_translate_pdma_value +( + uint32_t pdma_value, + adc_channel_id_t * channel_id +); + +/** @} */ + +/*=========================================================================*//** + @defgroup group12 Dynamic Linear Transform Control Functions + The following functions are used to dynamically adjust the linear transform + applied to analog input samples by the post processing engine: + - ACE_get_default_m_factor() + - ACE_get_default_c_offset() + - ACE_set_linear_transform() + The post processing engine performs a linear transform on analog input samples + obtained from the sample sequencing engine. The main purpose of this linear + transform is to apply part specific factory calibration to the analog samples + in order to achieve high accuracy. A second user specified linear transform + can also be optionally applied to the analog samples. This second linear + transform can be used to adjust for board level calibration or application + specific tuning. The functions described in this section apply to the user + defined transform. Factory calibration will not be affected by the use of the + ACE_set_linear_transform() function. + Note: + The post processing engine actually only performs one single linear + transform on analog samples. This transform takes into account factory + calibration and the user defined transform. The applied y = m.x + c + transform uses an m factor equal to m1.m2.mext and c offset equal to + (m2.c1.mext) + (c2.mext) where m1 and c1 are the factory calibration factor + and offset; m2 and c2 are the user defined transform factor and offset; and + mext is a factory calibration factor depending on the reference voltage + used by the ADC generating the sample. + @{ + *//*=========================================================================*/ + + +/*------------------------------------------------------------------------*//** + The ACE_get_default_m_factor() function retrieves the default value of the m + factor of the user defined linear transform applied by the post processing + engine to analog samples. The user defined linear transform m factor default + value is selected in the ACE configurator tool. + + @param channel_handle + The channel_handle parameter identifies one of the analog input channels + monitored by the ACE. The available channel handle values can be found in + the ace_handles.h file located in the .\drivers_config\mss_ace + subdirectory. The channel handle value can also be retrieved through a call + to ACE_get_channel_handle() when the name of the channel is known, or by + iterating though all analog input channel using the ACE_get_first_channel() + and ACE_get_next_channel(). + + @return + The ACE_get_default_m_factor() function returns the user transform m factor + default value. It is a signed 16-bit number representing a factor in the + range -2 to +1.99993896484375. The value of the m factor is obtained by + multiplying the return value’s absolute value by 2-14. + */ +int16_t ACE_get_default_m_factor +( + ace_channel_handle_t channel_handle +); + +/*------------------------------------------------------------------------*//** + The ACE_get_default_c_offset() function retrieves the default value of the c + offset of the user defined linear transform applied by the post processing + engine to analog samples. The user defined linear transform c offset default + value is selected in the ACE configurator tool. + + @param channel_handle + The channel_handle parameter identifies one of the analog input channels + monitored by the ACE. The available channel handle values can be found in + the ace_handles.h file located in the .\drivers_config\mss_ace + subdirectory. The channel handle value can also be retrieved through a call + to ACE_get_channel_handle() when the name of the channel is known, or by + iterating though all analog input channel using the ACE_get_first_channel() + and ACE_get_next_channel(). + + @return + The ACE_get_default_c_offset() function returns the user linear transform’s + c offset default value. It is a signed 16-bit number representing a factor + in the range -2 to +1.99993896484375. The value of the c offset is obtained + by multiplying the return value’s absolute value by 2-14. + */ +int16_t ACE_get_default_c_offset +( + ace_channel_handle_t channel_handle +); + +/*------------------------------------------------------------------------*//** + The ACE_set_linear_transform() function allows adjusting the user defined + linear transform applied to analog input samples by the post processing + engine. The linear transform is of the form y = m.x + b where the m factor + and c offset are in the range -2 to +1.99993896484375. + + @param channel_handle + The channel_handle parameter identifies one of the analog input channels + monitored by the ACE. The available channel handle values can be found in + the ace_handles.h file located in the .\drivers_config\mss_ace + subdirectory. The channel handle value can also be retrieved through a call + to ACE_get_channel_handle() when the name of the channel is known, or by + iterating though all analog input channel using the ACE_get_first_channel() + and ACE_get_next_channel(). + + @param m2 + The m2 parameter specifies the user defined transform’s m factor. It is a + signed 16-bit number representing a factor in the range -2 to + +1.99993896484375. The value of the m2 factor is obtained by multiplying the + parameter’s absolute value by 2^-14. For example, a value of 0x7000 + represents a 1.75 factor and a value of 0xE000 represents a -0.5 factor. + + @param c2 + The c2 parameter specifies the user defined transform’s c offset. It is a + signed 16-bit number representing an offset in the range -2 to + +1.99993896484375. The value of the c2 offset is obtained by multiplying the + parameter’s absolute value by 2^-14. For example, a value of 0x1000 represents + a 0.25 offset and a value of 0xB000 represents a -1.25 offset. + + @code + void reset_to_default(ace_channel_handle_t channel_handle) + { + int16_t m; + int16_t c; + + m = ACE_get_default_m_factor(channel_handle); + c = ACE_get_default_c_offset(channel_handle); + ACE_set_linear_transform(channel_handle, m, c); + } + @endcode + */ +void ACE_set_linear_transform +( + ace_channel_handle_t channel_handle, + int16_t m2, + int16_t c2 +); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __MSS_ACE_H_ */ diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/mss_ace_configurator.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/mss_ace_configurator.h new file mode 100644 index 000000000..2621f5375 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/mss_ace_configurator.h @@ -0,0 +1,622 @@ +/******************************************************************************* + * (c) Copyright 2009 Actel Corporation. All rights reserved. + * + * SVN $Revision: 2841 $ + * SVN $Date: 2010-07-20 18:10:00 +0100 (Tue, 20 Jul 2010) $ + */ + +/*=========================================================================*//** + @mainpage ACE Configurator data provided to ACE Driver. + + @section intro_sec Introduction + This file contains the definition of data structures used by the ACE + Configurator software tool for sharing information about the ACE configuration + with the ACE driver. It also contains the API for accessor functions used by + the ACE driver to extract relevant information from these data structures. + *//*=========================================================================*/ +#ifndef __MSS_ACE_CONFIGURATOR_H_ +#define __MSS_ACE_CONFIGURATOR_H_ + +#include "mss_ace.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*-------------------------------------------------------------------------*//** + Post Processing Engine (PPE) flags IDs. + */ +typedef enum +{ + PPE_FLAGS0_0 = 0, + PPE_FLAGS0_1 = 1, + PPE_FLAGS0_2 = 2, + PPE_FLAGS0_3 = 3, + PPE_FLAGS0_4 = 4, + PPE_FLAGS0_5 = 5, + PPE_FLAGS0_6 = 6, + PPE_FLAGS0_7 = 7, + PPE_FLAGS0_8 = 8, + PPE_FLAGS0_9 = 9, + PPE_FLAGS0_10 = 10, + PPE_FLAGS0_11 = 11, + PPE_FLAGS0_12 = 12, + PPE_FLAGS0_13 = 13, + PPE_FLAGS0_14 = 14, + PPE_FLAGS0_15 = 15, + PPE_FLAGS0_16 = 16, + PPE_FLAGS0_17 = 17, + PPE_FLAGS0_18 = 18, + PPE_FLAGS0_19 = 19, + PPE_FLAGS0_20 = 20, + PPE_FLAGS0_21 = 21, + PPE_FLAGS0_22 = 22, + PPE_FLAGS0_23 = 23, + PPE_FLAGS0_24 = 24, + PPE_FLAGS0_25 = 25, + PPE_FLAGS0_26 = 26, + PPE_FLAGS0_27 = 27, + PPE_FLAGS0_28 = 28, + PPE_FLAGS0_29 = 29, + PPE_FLAGS0_30 = 30, + PPE_FLAGS0_31 = 31, + PPE_FLAGS1_0 = 32, + PPE_FLAGS1_1 = 33, + PPE_FLAGS1_2 = 34, + PPE_FLAGS1_3 = 35, + PPE_FLAGS1_4 = 36, + PPE_FLAGS1_5 = 37, + PPE_FLAGS1_6 = 38, + PPE_FLAGS1_7 = 39, + PPE_FLAGS1_8 = 40, + PPE_FLAGS1_9 = 41, + PPE_FLAGS1_10 = 42, + PPE_FLAGS1_11 = 43, + PPE_FLAGS1_12 = 44, + PPE_FLAGS1_13 = 45, + PPE_FLAGS1_14 = 46, + PPE_FLAGS1_15 = 47, + PPE_FLAGS1_16 = 48, + PPE_FLAGS1_17 = 49, + PPE_FLAGS1_18 = 50, + PPE_FLAGS1_19 = 51, + PPE_FLAGS1_20 = 52, + PPE_FLAGS1_21 = 53, + PPE_FLAGS1_22 = 54, + PPE_FLAGS1_23 = 55, + PPE_FLAGS1_24 = 56, + PPE_FLAGS1_25 = 57, + PPE_FLAGS1_26 = 58, + PPE_FLAGS1_27 = 59, + PPE_FLAGS1_28 = 60, + PPE_FLAGS1_29 = 61, + PPE_FLAGS1_30 = 62, + PPE_FLAGS1_31 = 63, + PPE_FLAGS2_0 = 64, + PPE_FLAGS2_1 = 65, + PPE_FLAGS2_2 = 66, + PPE_FLAGS2_3 = 67, + PPE_FLAGS2_4 = 68, + PPE_FLAGS2_5 = 69, + PPE_FLAGS2_6 = 70, + PPE_FLAGS2_7 = 71, + PPE_FLAGS2_8 = 72, + PPE_FLAGS2_9 = 73, + PPE_FLAGS2_10 = 74, + PPE_FLAGS2_11 = 75, + PPE_FLAGS2_12 = 76, + PPE_FLAGS2_13 = 77, + PPE_FLAGS2_14 = 78, + PPE_FLAGS2_15 = 79, + PPE_FLAGS2_16 = 80, + PPE_FLAGS2_17 = 81, + PPE_FLAGS2_18 = 82, + PPE_FLAGS2_19 = 83, + PPE_FLAGS2_20 = 84, + PPE_FLAGS2_21 = 85, + PPE_FLAGS2_22 = 86, + PPE_FLAGS2_23 = 87, + PPE_FLAGS2_24 = 88, + PPE_FLAGS2_25 = 89, + PPE_FLAGS2_26 = 90, + PPE_FLAGS2_27 = 91, + PPE_FLAGS2_28 = 92, + PPE_FLAGS2_29 = 93, + PPE_FLAGS2_30 = 94, + PPE_FLAGS2_31 = 95, + PPE_FLAGS3_0 = 96, + PPE_FLAGS3_1 = 97, + PPE_FLAGS3_2 = 98, + PPE_FLAGS3_3 = 99, + PPE_FLAGS3_4 = 100, + PPE_FLAGS3_5 = 101, + PPE_FLAGS3_6 = 102, + PPE_FLAGS3_7 = 103, + PPE_FLAGS3_8 = 104, + PPE_FLAGS3_9 = 105, + PPE_FLAGS3_10 = 106, + PPE_FLAGS3_11 = 107, + PPE_FLAGS3_12 = 108, + PPE_FLAGS3_13 = 109, + PPE_FLAGS3_14 = 110, + PPE_FLAGS3_15 = 111, + PPE_FLAGS3_16 = 112, + PPE_FLAGS3_17 = 113, + PPE_FLAGS3_18 = 114, + PPE_FLAGS3_19 = 115, + PPE_FLAGS3_20 = 116, + PPE_FLAGS3_21 = 117, + PPE_FLAGS3_22 = 118, + PPE_FLAGS3_23 = 119, + PPE_FLAGS3_24 = 120, + PPE_FLAGS3_25 = 121, + PPE_FLAGS3_26 = 122, + PPE_FLAGS3_27 = 123, + PPE_FLAGS3_28 = 124, + PPE_FLAGS3_29 = 125, + PPE_FLAGS3_30 = 126, + PPE_FLAGS3_31 = 127, + PPE_SFFLAGS_0 = 128, + PPE_SFFLAGS_1 = 129, + PPE_SFFLAGS_2 = 130, + PPE_SFFLAGS_3 = 131, + PPE_SFFLAGS_4 = 132, + PPE_SFFLAGS_5 = 133, + PPE_SFFLAGS_6 = 134, + PPE_SFFLAGS_7 = 135, + PPE_SFFLAGS_8 = 136, + PPE_SFFLAGS_9 = 137, + PPE_SFFLAGS_10 = 138, + PPE_SFFLAGS_11 = 139, + PPE_SFFLAGS_12 = 140, + PPE_SFFLAGS_13 = 141, + PPE_SFFLAGS_14 = 142, + PPE_SFFLAGS_15 = 143, + PPE_SFFLAGS_16 = 144, + PPE_SFFLAGS_17 = 145, + PPE_SFFLAGS_18 = 146, + PPE_SFFLAGS_19 = 147, + PPE_SFFLAGS_20 = 148, + PPE_SFFLAGS_21 = 149, + PPE_SFFLAGS_22 = 150, + PPE_SFFLAGS_23 = 151, + PPE_SFFLAGS_24 = 152, + PPE_SFFLAGS_25 = 153, + PPE_SFFLAGS_26 = 154, + PPE_SFFLAGS_27 = 155, + PPE_SFFLAGS_28 = 156, + PPE_SFFLAGS_29 = 157, + PPE_SFFLAGS_30 = 158, + PPE_SFFLAGS_31 = 159, + NB_OF_PPE_FLAGS = 160 +} ppe_flag_id_t; + +/*-------------------------------------------------------------------------*//** + Flag types. + The following defines are used to indicate the type of flag selected in the + ACE configurator. + */ +/** + A flag configured as BASIC_THRESHOLD_OVER will be asserted when the value of + the input channel exceeds the value of the flag threshold. The flag will be + de-asserted once the value of the input channel falls back under the threshold + value. No hysteresis or state filtering is applied to the flag. + */ +#define BASIC_THRESHOLD_OVER 0u + +/** + A flag configured as BASIC_THRESHOLD_UNDER will be asserted when the value of + the input channel falls under the value of the flag threshold. The flag will be + de-asserted once the value of the input channel exceeds the threshold value. + No hysteresis or state filtering is applied to the flag. + */ +#define BASIC_THRESHOLD_UNDER 1u + +/** + A flag configured as STATE_FILTERED_OVER will be asserted when n consecutive + samples of the analog input are seen to exceed the value of the flag threshold, + where n is the number selected in the "assert samples" option of the ACE + configuration softwaretool flag's configuration. + The flag will be de-asserted once m consecutive samples as seen below the flag + threshold value, where m is the number selected in the "deassert samples" + option of the flag's configuration user interface. + */ +#define STATE_FILTERED_OVER 2u + +/** + A flag configured as STATE_FILTERED_UNDER will be asserted when n consecutive + samples of the analog input are seen below the value of the flag threshold, + where n is the number selected in the "assert samples" option of the ACE + configuration softwaretool flag's configuration. + The flag will be de-asserted once m consecutive samples as seen to exceed the + flag threshold value, where m is the number selected in the "deassert samples" + option of the flag's configuration user interface. + */ +#define STATE_FILTERED_UNDER 3u + +/** + A flag configured as DUAL_HYSTERESIS_OVER will be asserted when the value + of the input channel exceeds the threshold value plus the hysteresis value. + The flag will be deasserted when the value of the input channel falls under the + threshold value minus the hysteresis value. + */ +#define DUAL_HYSTERESIS_OVER 4u + +/** + A flag configured as DUAL_HYSTERESIS_UNDER will be asserted when the value + of the input channel falls under the threshold value minus the hysteresis value. + The flag will be deasserted when the value of the input channel exceeds the + threshold value plus the hysteresis value. + */ +#define DUAL_HYSTERESIS_UNDER 5u + +/** + A flag configured as IPMI_HYSTERESIS_OVER will be asserted when the value + of the input channel exceeds the threshold value. The flag will be deasserted + when the value of the input channel falls under the threshold value minus the + hysteresis value. + */ +#define IPMI_HYSTERESIS_OVER 6u + +/** + A flag configured as IPMI_HYSTERESIS_UNDER will be asserted when the value + of the input channel falls under the threshold value. The flag will be + deasserted when the value of the input channel exceeds the threshold value + plus the hysteresis value. + */ +#define IPMI_HYSTERESIS_UNDER 7u + +/*-------------------------------------------------------------------------*//** + State filtered flag configuration. + */ +typedef struct __state_filtering_cfg +{ + /** + Number of consecutive samples required for flag assertion. + */ + uint8_t assert_samples; + + /** + Number of consecutive samples required for flag deassertion. + */ + uint8_t deassert_samples; +} state_filtering_cfg_t; + +/*-------------------------------------------------------------------------*//** + Post Processing Engine generated flag descriptor. + */ +typedef struct +{ + /** + Pointer to a zero-terminated string identifying the flag described by this + structure. This unique flag name is the name selected in the ACE configurator + software tool when creating a flag. + The flag unique name contains both the name of the monitored input channel + and the name of the flag generated based the level of that input separated + by ":". For example, the unique name for the flag called "CriticalOver" + raised when the input channel called "MainSupply" reaches a critical level + would be named "MainSupply:CriticalOver". + */ + const uint8_t * p_sz_flag_name; + + /** + The flag_id element identifies which PPE hardware flag will be asserted + when the flag conditions are found to be met by the Post Processing Engine. + This flag_id is typically used by the ACE driver to determine which ACE + register is used to enable, disable and clear interrupts on the associated + flag. + */ + ppe_flag_id_t flag_id; + + /** + The flag_type element specifies the type of the described flag. It is + specified using one of the following: + - BASIC_THRESHOLD_OVER + - BASIC_THRESHOLD_UNDER + - STATE_FILTERED_OVER + - STATE_FILTERED_UNDER + - DUAL_HYSTERESIS_OVER + - DUAL_HYSTERESIS_UNDER + - IPMI_HYSTERESIS_OVER + - IPMI_HYSTERESIS_UNDER + */ + uint8_t flag_type; + + /** + PPE RAM offset of flag threshold level. + This is the 32-bit word offset within the Post Processing Engine RAM where + the threshold associated with this flag is stored. This is used to allow + the ACE driver dynamically modifying the threshold beyond which a flag is + asserted. + In the case of hysteresis flags, threshold_ppe_offset indicates the + start location of two consecutive PPE RAM words containing the ADC value + of the hysteresis low limit followed by the ADC value for the high + hysteresis limit. + */ + uint16_t threshold_ppe_offset; + + /** + The default_threshold element specifies the value of the flag's threshold + selected in the ACE Configurator. It is the ADC value for which the flag + would be raised if hysteresis was not applied. + */ + uint16_t default_threshold; + + /** + The flag_properties takes a different meaning depending whether the flag is + an hysteresis flag or a state filtered flag. + + Hysteresis flags: + The flag_properties element specifies the ADC value to be applied as + hysteresis to the threshold value that was selected in the ACE Configurator. + A non-zero value indicates that an hysteresis must be applied and that + threshold_ppe_offset refers to the first of the two ADC values defining + the hysteresis applied to the input signal. + + State filtered flags: + The flag_properties element specifies the number of consecutive samples that + must be over or under the threshold value for the flag state to change. + */ + uint16_t flag_properties; + + /** + The channel_handle element specifies the monitored analog input channel. + It can be used as parameter to a call to function ACE_get_ppe_sample() in + order to read the current value of the analog input channel which caused + the flag described by this structure to be raised. + */ + ace_channel_handle_t channel_handle; + +} ppe_flag_desc_t; + +/*-------------------------------------------------------------------------*//** + The ace_procedure_desc_t structure is used as a procedure descriptor. It + contains all information required by the ACE driver to use and manage an ACE + procedure that was created using the ACE Configurator software tool. + */ +typedef struct +{ + /** + Pointer to a zero-terminated string identifying an ACE procedure. + This procedure name is the one selected when created procedures using the + ACE Configurator software tool. + */ + const uint8_t * p_sz_proc_name; + + /** + Sample Sequencing Engine procedure loop start program counter value. + */ + uint16_t sse_loop_pc; + + /** + Sample Sequencing Engine microcode offset. + This is the 16-bit instruction offset from which the SSE microcode for the + procedure must be loaded at into the ACE SSE RAM. + This is also the value that must be writtent into one of the ACE's SSE program + counter registers in order to start the procedure after having loaded its + microcode into SSE RAM. The actual program counter register written depends + on the analog module used by the procedure. It is determined by the value + of this structure's sse_pc_id element. + */ + uint16_t sse_load_offset; + + /** + Sample Sequencing Engine microcode length. + This is the number of 16-bit SSE instructions that must be loaded into + SSE RAM in order to load the procedure into the ACE. + */ + uint16_t sse_ucode_length; + + /** + Pointer to ucode. + */ + const uint16_t * sse_ucode; + + /** + SSE program counter ID. + This value identifies whether the procedure is used to control analog + module 0, 1 or 2. It is used to know which SSE program counter should + be set when starting the procedure. + */ + uint8_t sse_pc_id; +} ace_procedure_desc_t; + +/*-------------------------------------------------------------------------*//** + The ace_channel_desc_t structure is used as an analog input channel + descriptor. It contains the name of a channel as selected in the ACE + Configurator software tool and the identifier used to identify the ADC channel + to which the analog input signal is connected. + */ +typedef struct +{ + /** + Analog input signal name as selected in the ACE Configurator software tool. + */ + const uint8_t * p_sz_channel_name; + + /** + Analog block input channel connected to the input signal. + */ + adc_channel_id_t signal_id; + + /** + Offset into Post Processing Engine RAM where the result of post processing + on sample for the signal will be stored. + */ + uint16_t signal_ppe_offset; + + /** + Number of PPE generated flags associated with the analog input channel + described by this structure. The nb_of_flags specifies the number of items + found in the p_flags_array array. + */ + uint16_t nb_of_flags; + + /** + The p_flags_array element is a pointer to an array of indexes into the + g_ppe_flags_desc_table flag descriptors table. The array it points to + lists the flags generated base don the value of the analog input channel + described by this structure. + */ + const uint16_t * p_flags_array; + +} ace_channel_desc_t; + +/*-------------------------------------------------------------------------*//** + struct ace_config_desc_t + The ace_config_descr_t structure is used to provide information about the + configuration of the ACE and analog block. A single instance of this structure + is intended to be used to inform the ACE driver of the ACE configuration + seleted using the ACE Configurator software tool and programmed into the ACE + hardware at system boot time. + */ +typedef struct +{ + /*-------------------------------------------------------------------------- + * Procedures information + */ + /** + Procedure descriptors table location. + This is a pointer to an array of procedure descriptors. + @see nb_of_procedures + */ + ace_procedure_desc_t * proc_descr_table; + + /** + Total number of available procedures. This indicates the number of elements + of the procedure descriptor array. + @see proc_descr_table + */ + uint16_t nb_of_procedures; + + /** + Number of procedures loaded into the ACE hardware at system boot time. + @see boot_loaded_proc_idx_list + */ + uint16_t nb_boot_loaded_proc; + /** + Pointer to list of procedures loaded into the ACE hardware at system boot + time. That list contains the indexes into the procedure descriptors array + of the procedures loaded into the ACE hardware. + @see nb_boot_loaded_proc + */ + uint16_t * boot_loaded_proc_idx_list; + + /*-------------------------------------------------------------------------- + * Analog to Digital Converter signals + */ + /** + Total number of configured analog input signals. + This is the number of analog input signals that were added to the ACE + configuration using the ACE Configurator software tool. It is also the + number of elements in the signal descriptor table pointed to by this + structure's signals_descr_table field. + @see signals_descr_table + */ + uint16_t nb_of_signals; + + /** + Signal descriptors table location. + This is a pointer to an array of signal descriptors describing every + configured analog input signals. + @see nb_of_signals + */ + ace_channel_desc_t * signals_descr_table; + + /*-------------------------------------------------------------------------- + * One Bit DACs + */ + /** + One Bit DAC (OBD) names as specified in ACE configurator software tool. + This array is indexed on the analog block number. i.e. sz_obd_names[0] + contains the name used to identify the OBD contained in analog module 0. + A value of 0 in this array indicates that no name was assigned to the + associated OBD. + */ + const uint8_t * sz_obd_names[3]; + + /*-------------------------------------------------------------------------- + * PPE generated flags + */ + /** + Flag descriptors array location. + This is a pointer to an array of ppe_flag_desc_t structures describing the + properties of each of the flags generated by the Post Processing Engine. + The size of that array is specified by the nb_of_flags element of this + structure. + */ + ppe_flag_desc_t * flags_descr_table; + + /** + Number of flags used in the ACE Configurator generated configuration. + */ + uint8_t nb_of_flags; + + /*-------------------------------------------------------------------------- + * Analog comparators + */ + /** + * + */ +} ace_config_desc_t; + + +/*-------------------------------------------------------------------------*//** + The ace_adc_config_t data structure is used by the ACE configurator to inform + the ACE driver of an analog to digital converter's configuration. + */ +typedef struct +{ + /** + ADC resolution. Values can be 256, 1024 or 4096 depending whether the ADC + is configured for 8, 10 or 12 bits. + */ + uint16_t adc_resolution; + + /** + VA_REF value in milli-Volts. This should be set to 2560 if internal VAREF + is used. + */ + uint16_t va_ref; + +} ace_adc_config_t; + +/*-------------------------------------------------------------------------*//** + The ppe_transforms_desc_t data structure is used by the ACE configurator to + inform the ACE driver of the location of the "m" factor and "c" offset used + by the PPE to perform a linear transform of the form y = m*x + c. This linear + transform is used to apply calibration to the ADC samples. It can also include + a user defined linear transform specified by the user using the ACE + configurator. The factor and offset of the user defined transform is included + in the default_m2 and default_c2 items. + */ +typedef struct +{ + /** + Offset into Post Processing Engine RAM where the linear transform m factor + is stored. + */ + uint16_t m_ppe_offset; + + /** + Offset into Post Processing Engine RAM where the linear transform c offset + is stored. + */ + uint16_t c_ppe_offset; + + /** + Default value of the user defined linear transform m2 factor. + */ + int16_t default_m2; + + /** + Default value of the user defined linear transform c2 offset. + */ + int16_t default_c2; +} ppe_transforms_desc_t; + +#ifdef __cplusplus +} +#endif + +#endif /* __MSS_ACE_CONFIGURATOR_H_ */ diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/mtd_data.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/mtd_data.h new file mode 100644 index 000000000..431f28f78 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ace/mtd_data.h @@ -0,0 +1,104 @@ +/******************************************************************************* + * (c) Copyright 2008 Actel Corporation. All rights reserved. + * + * Manufacturing Test Data data structures. + * This header files specified the layout of the various data structures used + * to store manaufacturing test data within eNVM. + * + * SVN $Revision: 700 $ + * SVN $Date: 2009-03-13 13:22:03 +0000 (Fri, 13 Mar 2009) $ + */ +#ifndef MTD_DATA_H +#define MTD_DATA_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Analog block specifications + */ +#define NB_OF_QUADS 6 +#define NB_OF_ABPS_PER_QUAD 2 +#define TOTAL_NB_OF_ABPS (NB_OF_QUADS * NB_OF_ABPS_PER_QUAD) +#define NB_OF_ABPS_RANGES 4 +#define NB_OF_ANALOG_MODULES 3 +#define NB_OF_OBD_MODES 2 +#define NB_OF_QUADS_PER_MODULE 2 +#define NB_OF_CHOPPING_OPTIONS 2 +#define NB_OF_DIRECT_INPUTS_PER_ADC 4 + +#define NB_OF_ADC_CHANNELS 13 + +/*------------------------------------------------------------------------------ + * mtd_global_settings_t + *------------------------------------------------------------------------------ + * This typedef specifies the layout of the data structure holding the + * manufacturing test data global settings. + */ +typedef struct __mtd_global_settings_t +{ + uint16_t crc16; + uint8_t serial[6]; + uint32_t revision; + uint16_t sram_repair[8]; + uint16_t varef_m; + uint16_t spare; + uint8_t big_dec; + uint8_t reserved0; + uint16_t reserved1; +} mtd_global_settings_t; + +/*------------------------------------------------------------------------------ + * mtd_abps_trim_t + *------------------------------------------------------------------------------ + * The following data structure is used to store ABPS trimming information. + */ +typedef struct __mtd_abps_trim_t +{ + uint8_t dacdec; + uint8_t negtrim_per4_per3b_gtdec; +} mtd_abps_trim_t; + + +/*------------------------------------------------------------------------------ + * mtd_calibration_mc_t + *------------------------------------------------------------------------------ + * The following data structure is used to store M and C calibration + * coefficients. + */ +typedef struct __mtd_calibration_mc_t +{ + uint16_t m; + uint16_t c; +} mtd_calibration_mc_t; + + +/*------------------------------------------------------------------------------ + * mtd_data_t + *------------------------------------------------------------------------------ + * The following data structure is used to hold the full set of manufacturing + * test data. + */ +typedef struct __mtd_data_t +{ + mtd_global_settings_t global_settings; + mtd_abps_trim_t abps_trimming[NB_OF_QUADS][NB_OF_ABPS_PER_QUAD][NB_OF_ABPS_RANGES]; + uint8_t odb_trimming[NB_OF_ANALOG_MODULES][NB_OF_OBD_MODES][NB_OF_CHOPPING_OPTIONS]; + mtd_calibration_mc_t abps_calibration[NB_OF_QUADS][NB_OF_ABPS_PER_QUAD][NB_OF_ABPS_RANGES]; + mtd_calibration_mc_t obd_calibration[NB_OF_ANALOG_MODULES][NB_OF_OBD_MODES][NB_OF_CHOPPING_OPTIONS]; + mtd_calibration_mc_t cm_calibration[NB_OF_QUADS]; + mtd_calibration_mc_t tm_calibration[NB_OF_QUADS]; + mtd_calibration_mc_t quads_direct_input_cal[NB_OF_QUADS][2]; + mtd_calibration_mc_t adc_direct_input_cal[NB_OF_ANALOG_MODULES][NB_OF_DIRECT_INPUTS_PER_ADC]; + uint16_t comparators_offsets[NB_OF_QUADS]; + uint32_t ccc_delays_cal; +} mtd_data_t; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/crc32.c b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/crc32.c new file mode 100644 index 000000000..fc17e5298 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/crc32.c @@ -0,0 +1,103 @@ +/***************************************************************************//** + * @file + * crc32 source file. + * + * CRC-32-IEEE 802.3 + * x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + + * x^4 + x^2 + x + 1 + * + * (c) Copyright 2007 Actel Corporation + * + * SVN $Revision: 2369 $ + * SVN $Date: 2010-03-01 18:31:45 +0000 (Mon, 01 Mar 2010) $ + ******************************************************************************/ + + #ifdef __cplusplus +extern "C" { +#endif + +#include "crc32.h" + +static const uint32_t crc32_table[] = { + 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, 0x706af48fUL, + 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, 0xe0d5e91eUL, 0x97d2d988UL, + 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, + 0xf3b97148UL, 0x84be41deUL, 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, + 0x136c9856UL, 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, + 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, 0xa2677172UL, + 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, 0x35b5a8faUL, 0x42b2986cUL, + 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, + 0x26d930acUL, 0x51de003aUL, 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, + 0xcfba9599UL, 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, + 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, 0x01db7106UL, + 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, 0x9fbfe4a5UL, 0xe8b8d433UL, + 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, + 0x91646c97UL, 0xe6635c01UL, 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, + 0x6c0695edUL, 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, + 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, 0xfbd44c65UL, + 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, 0x4adfa541UL, 0x3dd895d7UL, + 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, + 0x44042d73UL, 0x33031de5UL, 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, + 0xbe0b1010UL, 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, + 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, 0x2eb40d81UL, + 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, 0x03b6e20cUL, 0x74b1d29aUL, + 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, + 0x0d6d6a3eUL, 0x7a6a5aa8UL, 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, + 0xf00f9344UL, 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, + 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, 0x67dd4accUL, + 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, 0xd6d6a3e8UL, 0xa1d1937eUL, + 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, + 0xd80d2bdaUL, 0xaf0a1b4cUL, 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, + 0x316e8eefUL, 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, + 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, 0xb2bd0b28UL, + 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, 0x2cd99e8bUL, 0x5bdeae1dUL, + 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, + 0x72076785UL, 0x05005713UL, 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, + 0x92d28e9bUL, 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, + 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, 0x18b74777UL, + 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, 0x8f659effUL, 0xf862ae69UL, + 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, + 0xa7672661UL, 0xd06016f7UL, 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, + 0x40df0b66UL, 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, + 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, 0xcdd70693UL, + 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, 0x5d681b02UL, 0x2a6f2b94UL, + 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, 0x2d02ef8dUL +}; + +/** + * Calculates 32 bits CRC value of given data. + */ +uint32_t +mss_mac_crc32 +( + uint32_t value, + const uint8_t *data, + uint32_t data_length +) +{ + uint32_t a; + + for(a=0; a> 8); + } + + return value; +} + +/** + * Calculates 32 bits CRC value of given data, using standart Ethernet CRC + * function. + */ +uint32_t +mss_ethernet_crc +( + const uint8_t *data, + uint32_t data_length +) +{ + return mss_mac_crc32( 0xffffffffUL, data, data_length ); +} + +#ifdef __cplusplus +} +#endif diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/crc32.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/crc32.h new file mode 100644 index 000000000..ce500a6f2 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/crc32.h @@ -0,0 +1,46 @@ +/***************************************************************************//** + * @file + * crc32 header file. + * + * (c) Copyright 2007 Actel Corporation + * + * SVN $Revision: 2369 $ + * SVN $Date: 2010-03-01 18:31:45 +0000 (Mon, 01 Mar 2010) $ + ******************************************************************************/ + +#ifndef __MSS_ETHERNET_MAC_CRC32_H +#define __MSS_ETHERNET_MAC_CRC32_H 1 + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Calculates 32 bits CRC value of given data. + */ +uint32_t +mss_mac_crc32 +( + uint32_t value, + const uint8_t *data, + uint32_t data_length +); + +/** + * Calculates 32 bits CRC value of given data, using standart Ethernet CRC + * function. + */ +uint32_t +mss_ethernet_crc +( + const uint8_t *data, + uint32_t data_length +); + +#ifdef __cplusplus +} +#endif + +#endif /* __MSS_ETHERNET_MAC_CRC32_H */ diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac.c b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac.c new file mode 100644 index 000000000..5ebea2eb6 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac.c @@ -0,0 +1,1543 @@ +/***************************************************************************//** + * @file + * SmartFusion MSS Ethernet MAC driver implementation. + * + * (c) Copyright 2007 Actel Corporation + * + * SVN $Revision: 2369 $ + * SVN $Date: 2010-03-01 18:31:45 +0000 (Mon, 01 Mar 2010) $ + * + ******************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "FreeRTOS.h" +#include "task.h" + +#include "crc32.h" + +#include "mss_ethernet_mac.h" +#include "mss_ethernet_mac_regs.h" +#include "mss_ethernet_mac_desc.h" +#include "mss_ethernet_mac_conf.h" +#include "../../CMSIS/mss_assert.h" + +#include "phy.h" + +/**************************** INTERNAL DEFINES ********************************/ + +#define MAC_CHECK(CHECK,ERRNO) \ + {if(!(CHECK)){g_mss_mac.last_error=(ERRNO); configASSERT((CHECK));}} + +/* + * Flags + */ +#define FLAG_MAC_INIT_DONE 1u +#define FLAG_PERFECT_FILTERING 2u +#define FLAG_CRC_DISABLE 4u +#define FLAG_EXCEED_LIMIT 8u + +/* + * Return types + */ +#define MAC_OK 0 +#define MAC_FAIL (-1) +#define MAC_WRONG_PARAMETER (-2) +#define MAC_TOO_BIG_PACKET (-3) +#define MAC_BUFFER_IS_FULL (-4) +#define MAC_NOT_ENOUGH_SPACE (-5) +#define MAC_TIME_OUT (-6) +#define MAC_TOO_SMALL_PACKET (-7) + +/* Allocating this many buffers will always ensure there is one free as, even +though TX_RING_SIZE is set to two, the two Tx descriptors will only ever point +to the same buffer. */ +#define macNUM_BUFFERS RX_RING_SIZE + TX_RING_SIZE + 1 +#define macBUFFER_SIZE 1488 + +/***************************************************************/ +MAC_instance_t g_mss_mac __attribute__((aligned(4))); + +/**************************** INTERNAL DATA ***********************************/ +#define ERROR_MESSAGE_COUNT 8 +#define MAX_ERROR_MESSAGE_WIDTH 40 +static const int8_t unknown_error[] = "Unknown error"; +static const int8_t ErrorMessages[][MAX_ERROR_MESSAGE_WIDTH] = { + "No error occured", + "Method failed", + "Wrong parameter pased to function", + "Frame is too long", + "Not enough space in buffer", + "Not enough space in buffer", + "Timed out", + "Frame is too small" +}; + +/* + * Null variables + */ +static MAC_instance_t* NULL_instance; +static uint8_t* NULL_buffer; +static MSS_MAC_callback_t NULL_callback; +unsigned char *uip_buf = NULL; + +/**************************** INTERNAL FUNCTIONS ******************************/ + +static int32_t MAC_test_instance( void ); + +static int32_t MAC_dismiss_bad_frames( void ); +static int32_t MAC_send_setup_frame( void ); + +static int32_t MAC_stop_transmission( void ); +static void MAC_start_transmission( void ); +static int32_t MAC_stop_receiving( void ); +static void MAC_start_receiving( void ); + +static void MAC_set_time_out( uint32_t time_out ); +static uint32_t MAC_get_time_out( void ); + +static void MAC_memset(uint8_t *s, uint8_t c, uint32_t n); +static void MAC_memcpy(uint8_t *dest, const uint8_t *src, uint32_t n); +static void MAC_memset_All(MAC_instance_t *s, uint32_t c); + +static unsigned char *MAC_obtain_buffer( void ); +static void MAC_release_buffer( unsigned char *pcBufferToRelease ); + +#if( TX_RING_SIZE != 2 ) + #error This uIP Ethernet driver required TX_RING_SIZE to be set to 2 +#endif + +/* Buffers that will dynamically be allocated to/from the Tx and Rx descriptors. */ +static unsigned char ucMACBuffers[ macNUM_BUFFERS ][ macBUFFER_SIZE ] __attribute__((aligned(4))); + +/* Each array position indicated whether or not the buffer of the same index +is currently allocated to a descriptor (pdFALSE) or is free for use (pdTRUE). */ +static unsigned char ucMACBufferInUse[ macNUM_BUFFERS ] = { 0 }; + +/***************************************************************************//** + * Initializes the Ethernet Controller. + * This function will prepare the Ethernet Controller for first time use in a + * given hardware/software configuration. This function should be called before + * any other Ethernet API functions are called. + * + * Initialization of registers - config registers, enable Tx/Rx interrupts, + * enable Tx/Rx, initialize MAC addr, init PHY, autonegotiation, MAC address + * filter table (unicats/multicast)/hash init + */ +void +MSS_MAC_init +( + uint8_t phy_address +) +{ + const uint8_t mac_address[6] = { DEFAULT_MAC_ADDRESS }; + int32_t a; + + /* To start with all buffers are free. */ + for( a = 0; a < macNUM_BUFFERS; a++ ) + { + ucMACBufferInUse[ a ] = pdFALSE; + } + + /* Try to reset chip */ + MAC_BITBAND->CSR0_SWR = 1u; + + do + { + vTaskDelay( 10 ); + } while ( 1u == MAC_BITBAND->CSR0_SWR ); + + /* Check reset values of some registers to constrol + * base address validity */ + configASSERT( MAC->CSR0 == 0xFE000000uL ); + configASSERT( MAC->CSR5 == 0xF0000000uL ); + configASSERT( MAC->CSR6 == 0x32000040uL ); + + /* Instance setup */ + MAC_memset_All( &g_mss_mac, 0u ); + + g_mss_mac.base_address = MAC_BASE; + g_mss_mac.phy_address = phy_address; + + for( a=0; 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(); + configASSERT( g_mss_mac.phy_address <= MSS_PHY_ADDRESS_MAX ); + } + + /* Reset PHY */ + PHY_reset(); + + /* Set flags */ + g_mss_mac.flags = FLAG_MAC_INIT_DONE | FLAG_PERFECT_FILTERING; + + /* Configure chip according to PHY status */ + MSS_MAC_auto_setup_link(); + + /* Set default MAC address and reset mac filters */ + MAC_memcpy( g_mss_mac.mac_address, mac_address, 6u ); + MSS_MAC_set_mac_filters( 0u, NULL_buffer ); + MAC_BITBAND->CSR6_RA = 1; /* Receive all. */ + MAC_BITBAND->CSR6_PR = 1; /* Promiscuous mode. */ + MSS_MAC_set_mac_address((uint8_t *)mac_address); + + /* Ensure uip_buf starts by pointing somewhere. */ + uip_buf = MAC_obtain_buffer(); +} + + +/***************************************************************************//** + * Sets the configuration of the Ethernet Controller. + * After the EthernetInit function has been called, this API function can be + * used to configure the various features of the Ethernet Controller. + * + * @param instance Pointer to a MAC_instance_t structure + * @param config The logical OR of the following values: + * - #MSS_MAC_CFG_RECEIVE_ALL + * - #MSS_MAC_CFG_TRANSMIT_THRESHOLD_MODE + * - #MSS_MSS_MAC_CFG_STORE_AND_FORWARD + * - #MAC_CFG_THRESHOLD_CONTROL_[00,01,10,11] + * - #MSS_MAC_CFG_FULL_DUPLEX_MODE + * - #MSS_MAC_CFG_PASS_ALL_MULTICAST + * - #MSS_MAC_CFG_PROMISCUOUS_MODE + * - #MSS_MAC_CFG_PASS_BAD_FRAMES + * @see MAC_get_configuration() + */ +void +MSS_MAC_configure +( + uint32_t configuration +) +{ + int32_t ret; + + configASSERT( MAC_test_instance() == MAC_OK ); + + ret = MAC_stop_transmission(); + configASSERT( ret == MAC_OK ); + + ret = MAC_stop_receiving(); + configASSERT( ret == MAC_OK ); + + MAC_BITBAND->CSR6_RA = (uint32_t)(((configuration & MSS_MAC_CFG_RECEIVE_ALL) != 0u) ? 1u : 0u ); + MAC_BITBAND->CSR6_TTM = (((configuration & MSS_MAC_CFG_TRANSMIT_THRESHOLD_MODE) != 0u) ? 1u : 0u ); + MAC_BITBAND->CSR6_SF = (uint32_t)(((configuration & MSS_MAC_CFG_STORE_AND_FORWARD) != 0u) ? 1u : 0u ); + + switch( configuration & MSS_MAC_CFG_THRESHOLD_CONTROL_11 ) { + case MSS_MAC_CFG_THRESHOLD_CONTROL_00: + MAC->CSR6 = MAC->CSR6 & ~CSR6_TR_MASK; + break; + case MSS_MAC_CFG_THRESHOLD_CONTROL_01: + MAC->CSR6 = (MAC->CSR6 & ~CSR6_TR_MASK) | ((uint32_t)1 << CSR6_TR_SHIFT ); + break; + case MSS_MAC_CFG_THRESHOLD_CONTROL_10: + MAC->CSR6 = (MAC->CSR6 & ~CSR6_TR_MASK) | ((uint32_t)2 << CSR6_TR_SHIFT ); + break; + case MSS_MAC_CFG_THRESHOLD_CONTROL_11: + MAC->CSR6 = (MAC->CSR6 & ~CSR6_TR_MASK) | ((uint32_t)3 << CSR6_TR_SHIFT ); + break; + default: + break; + } + MAC_BITBAND->CSR6_FD = (uint32_t)(((configuration & MSS_MAC_CFG_FULL_DUPLEX_MODE) != 0u) ? 1u : 0u ); + MAC_BITBAND->CSR6_PM = (uint32_t)(((configuration & MSS_MAC_CFG_PASS_ALL_MULTICAST) != 0u) ? 1u : 0u ); + MAC_BITBAND->CSR6_PR = (uint32_t)(((configuration & MSS_MAC_CFG_PROMISCUOUS_MODE) != 0u) ? 1u : 0u ); + MAC_BITBAND->CSR6_PB = (uint32_t)(((configuration & MSS_MAC_CFG_PASS_BAD_FRAMES) != 0u) ? 1u : 0u ); + PHY_set_link_type( (uint8_t) + ((((configuration & MSS_MAC_CFG_TRANSMIT_THRESHOLD_MODE) != 0u) ? MSS_MAC_LINK_STATUS_100MB : 0u ) | + (((configuration & MSS_MAC_CFG_FULL_DUPLEX_MODE) != 0u) ? MSS_MAC_LINK_STATUS_FDX : 0u )) ); + + MSS_MAC_auto_setup_link(); +} + + +/***************************************************************************//** + * Returns the configuration of the Ethernet Controller. + * + * @param instance Pointer to a MAC_instance_t structure + * @return The logical OR of the following values: + * - #MSS_MAC_CFG_RECEIVE_ALL + * - #MSS_MAC_CFG_TRANSMIT_THRESHOLD_MODE + * - #MSS_MAC_CFG_STORE_AND_FORWARD + * - #MAC_CFG_THRESHOLD_CONTROL_[00,01,10,11] + * - #MSS_MAC_CFG_FULL_DUPLEX_MODE + * - #MSS_MAC_CFG_PASS_ALL_MULTICAST + * - #MSS_MAC_CFG_PROMISCUOUS_MODE + * - #MSS_MAC_CFG_INVERSE_FILTERING + * - #MSS_MAC_CFG_PASS_BAD_FRAMES + * - #MSS_MAC_CFG_HASH_ONLY_FILTERING_MODE + * - #MSS_MAC_CFG_HASH_PERFECT_RECEIVE_FILTERING_MODE + * @see MAC_configure() + */ +int32_t +MSS_MAC_get_configuration( void ) +{ + uint32_t configuration; + + configASSERT( MAC_test_instance() == MAC_OK ); + + configuration = 0u; + if( MAC_BITBAND->CSR6_RA != 0u ) { + configuration |= MSS_MAC_CFG_RECEIVE_ALL; + } + + if( MAC_BITBAND->CSR6_TTM != 0u ) { + configuration |= MSS_MAC_CFG_TRANSMIT_THRESHOLD_MODE; + } + + if( MAC_BITBAND->CSR6_SF != 0u ) { + configuration |= MSS_MAC_CFG_STORE_AND_FORWARD; + } + + switch( (MAC->CSR6 & CSR6_TR_MASK) >> CSR6_TR_SHIFT ) { + case 1: configuration |= MSS_MAC_CFG_THRESHOLD_CONTROL_01; break; + case 2: configuration |= MSS_MAC_CFG_THRESHOLD_CONTROL_10; break; + case 3: configuration |= MSS_MAC_CFG_THRESHOLD_CONTROL_11; break; + default: break; + } + if( MAC_BITBAND->CSR6_FD != 0u ) { + configuration |= MSS_MAC_CFG_FULL_DUPLEX_MODE; + } + + if( MAC_BITBAND->CSR6_PM != 0u ) { + configuration |= MSS_MAC_CFG_PASS_ALL_MULTICAST; + } + + if( MAC_BITBAND->CSR6_PR != 0u ) { + configuration |= MSS_MAC_CFG_PROMISCUOUS_MODE; + } + + if( MAC_BITBAND->CSR6_IF != 0u ) { + configuration |= MSS_MAC_CFG_INVERSE_FILTERING; + } + + if( MAC_BITBAND->CSR6_PB != 0u ) { + configuration |= MSS_MAC_CFG_PASS_BAD_FRAMES; + } + + if( MAC_BITBAND->CSR6_HO != 0u ) { + configuration |= MSS_MAC_CFG_HASH_ONLY_FILTERING_MODE; + } + + if( MAC_BITBAND->CSR6_HP != 0u ) { + configuration |= MSS_MAC_CFG_HASH_PERFECT_RECEIVE_FILTERING_MODE; + } + + return (int32_t)configuration; +} + + +/***************************************************************************//** + Sends a packet from the uIP stack to the Ethernet Controller. + The MSS_MAC_tx_packet() function is used to send a packet to the MSS Ethernet + MAC. This function writes uip_len bytes of the packet contained in uip_buf into + the transmit FIFO and then activates the transmitter for this packet. If space + is available in the FIFO, the function will return once pac_len bytes of the + packet have been placed into the FIFO and the transmitter has been started. + This function will not wait for the transmission to complete. + + @return + The function returns zero if a timeout occurs otherwise it returns size of the packet. + + @see MAC_rx_packet() + */ + +int32_t +MSS_MAC_tx_packet +( + unsigned short usLength +) +{ + uint32_t desc; + unsigned long ulDescriptor; + int32_t error = MAC_OK; + extern unsigned char *uip_buf; + + configASSERT( MAC_test_instance() == MAC_OK ); + + configASSERT( uip_buf != NULL_buffer ); + + configASSERT( usLength >= 12 ); + + if( (g_mss_mac.flags & FLAG_EXCEED_LIMIT) == 0u ) + { + configASSERT( usLength <= MSS_MAX_PACKET_SIZE ); + } + + /* Check if second descriptor is free, if it is then the first must + also be free. */ + if(((g_mss_mac.tx_descriptors[ 1 ].descriptor_0) & TDES0_OWN) == TDES0_OWN ) + { + error = MAC_BUFFER_IS_FULL; + } + + if( error == MAC_OK ) + { + /* Assumed TX_RING_SIZE == 2. */ + for( ulDescriptor = 0; ulDescriptor < TX_RING_SIZE; ulDescriptor++ ) + { + g_mss_mac.tx_descriptors[ ulDescriptor ].descriptor_1 = 0u; + + if( (g_mss_mac.flags & FLAG_CRC_DISABLE) != 0u ) { + g_mss_mac.tx_descriptors[ ulDescriptor ].descriptor_1 |= TDES1_AC; + } + + /* Every buffer can hold a full frame so they are always first and last + descriptor */ + g_mss_mac.tx_descriptors[ ulDescriptor ].descriptor_1 |= TDES1_LS | TDES1_FS | TDES1_IC; + + /* set data size */ + g_mss_mac.tx_descriptors[ ulDescriptor ].descriptor_1 |= usLength; + + /* reset end of ring */ + g_mss_mac.tx_descriptors[TX_RING_SIZE-1].descriptor_1 |= TDES1_TER; + + if( usLength > MSS_TX_BUFF_SIZE ) /* FLAG_EXCEED_LIMIT */ + { + usLength = (uint16_t)MSS_TX_BUFF_SIZE; + } + + /* The data buffer is assigned to the Tx descriptor. */ + g_mss_mac.tx_descriptors[ ulDescriptor ].buffer_1 = ( unsigned long ) uip_buf; + + /* update counters */ + desc = g_mss_mac.tx_descriptors[ ulDescriptor ].descriptor_0; + if( (desc & TDES0_LO) != 0u ) { + g_mss_mac.statistics.tx_loss_of_carrier++; + } + if( (desc & TDES0_NC) != 0u ) { + g_mss_mac.statistics.tx_no_carrier++; + } + if( (desc & TDES0_LC) != 0u ) { + g_mss_mac.statistics.tx_late_collision++; + } + if( (desc & TDES0_EC) != 0u ) { + g_mss_mac.statistics.tx_excessive_collision++; + } + if( (desc & TDES0_UF) != 0u ) { + g_mss_mac.statistics.tx_underflow_error++; + } + g_mss_mac.statistics.tx_collision_count += + (desc >> TDES0_CC_OFFSET) & TDES0_CC_MASK; + + /* Give ownership of descriptor to the MAC */ + g_mss_mac.tx_descriptors[ ulDescriptor ].descriptor_0 = RDES0_OWN; + } + + /* Start transmission */ + MAC_start_transmission(); + g_mss_mac.tx_desc_index = 0; + /* transmit poll demand */ + MAC->CSR1 = 1u; + } + + + + + if (error == MAC_OK) + { + /* The buffer uip_buf was pointing to is now under the control of the + MAC (it is being transmitted). Set uip_buf to point to a free buffer. */ + uip_buf = MAC_obtain_buffer(); + error = (int32_t)usLength; + } + else + { + error = 0; + } + return ( error ); +} + + +/***************************************************************************//** + * Returns available packet size. + * + * @param instance Pointer to a MAC_instance_t structure + * @return size of packet, bigger than 0, if a packet is available. + * If not, returns 0. + * @see MAC_rx_packet() + */ +int32_t +MSS_MAC_rx_pckt_size +( + void +) +{ + int32_t retval; + configASSERT( MAC_test_instance() == MAC_OK ); + + MAC_dismiss_bad_frames(); + + if( (g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 & RDES0_OWN) != 0u ) + { + /* Current descriptor is empty */ + retval = 0; + } + else + { + uint32_t frame_length; + frame_length = ( g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 >> RDES0_FL_OFFSET ) & RDES0_FL_MASK; + retval = (int32_t)( frame_length ); + } + return retval; +} + + +/***************************************************************************//** + * Receives a packet from the Ethernet Controller into the uIP stack. + * This function reads a packet from the receive FIFO of the controller and + * places it into uip_buf. + + * @return Size of packet if packet fits in uip_buf. + * 0 if there is no received packet. + * @see MAC_rx_pckt_size() + * @see MAC_tx_packet() + */ +int32_t +MSS_MAC_rx_packet +( + void +) +{ + uint16_t frame_length=0u; + + configASSERT( MAC_test_instance() == MAC_OK ); + + MAC_dismiss_bad_frames(); + + if( (g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 & RDES0_OWN) == 0u ) + { + frame_length = ( ( + g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 >> + RDES0_FL_OFFSET ) & RDES0_FL_MASK ); + + /* strip crc */ + frame_length -= 4u; + + if( frame_length > macBUFFER_SIZE ) { + return MAC_NOT_ENOUGH_SPACE; + } + + /* uip_buf is about to point to the buffer that contains the received + data, mark the buffer that uip_buf is currently pointing to as free + again. */ + MAC_release_buffer( uip_buf ); + uip_buf = ( unsigned char * ) g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].buffer_1; + + /* The buffer the Rx descriptor was pointing to is now in use by the + uIP stack - allocate a new buffer to the Rx descriptor. */ + g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].buffer_1 = ( unsigned long ) MAC_obtain_buffer(); + + MSS_MAC_prepare_rx_descriptor(); + } + return ((int32_t)frame_length); +} + + +/***************************************************************************//** + * Receives a packet from the Ethernet Controller. + * This function reads a packet from the receive FIFO of the controller and + * sets the address of pacData to the received data. + * If time_out parameter is zero the function will return + * immediately (after the copy operation if data is available. Otherwise the function + * will keep trying to read till time_out expires or data is read, if MSS_MAC_BLOCKING + * value is given as time_out, function will wait for the reception to complete. + * + * @param instance Pointer to a MAC_instance_t structure + * @param pacData The pointer to the packet data. + * @param time_out Time out value in milli seconds for receiving. + * if value is #MSS_MAC_BLOCKING, there will be no time out. + * if value is #MSS_MAC_NONBLOCKING, function will return immediately + * if there is no packet waiting. + * Otherwise value must be greater than 0 and smaller than + * 0x01000000. + * @return Size of packet if packet fits in pacData. + * 0 if there is no received packet. + * @see MAC_rx_pckt_size() + * @see MAC_tx_packet() + */ +int32_t +MSS_MAC_rx_packet_ptrset +( + uint8_t **pacData, + uint32_t time_out +) +{ + uint16_t frame_length = 0u; + int8_t exit = 0; + + configASSERT( MAC_test_instance() == MAC_OK ); + + configASSERT( (time_out == MSS_MAC_BLOCKING) || + (time_out == MSS_MAC_NONBLOCKING) || + ((time_out >= 1) && (time_out <= 0x01000000UL)) ); + + MAC_dismiss_bad_frames(); + + /* wait for a packet */ + if( time_out != MSS_MAC_BLOCKING ) { + if( time_out == MSS_MAC_NONBLOCKING ) { + MAC_set_time_out( 0u ); + } else { + MAC_set_time_out( time_out ); + } + } + + while( ((g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 & + RDES0_OWN) != 0u) && (exit == 0) ) + { + if( time_out != MSS_MAC_BLOCKING ) + { + if( MAC_get_time_out() == 0u ) { + exit = 1; + } + } + } + + if(exit == 0) + { + frame_length = ( ( + g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 >> + RDES0_FL_OFFSET ) & RDES0_FL_MASK ); + + /* strip crc */ + frame_length -= 4u; + + /* Here we are setting the buffer 'pacData' address to the address + RX descriptor address. After this is called, the following function + must be called 'MAC_prepare_rx_descriptor' + to prepare the current rx descriptor for receiving the next packet. + */ + *pacData = (uint8_t *)g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].buffer_1 ; + + } + return ((int32_t)frame_length); +} + +/***************************************************************************//** + * Returns the status of connection. + * + * @return the logical OR of the following values: + * #MSS_MAC_LINK_STATUS_LINK - Link up/down + * #MSS_MAC_LINK_STATUS_100MB - Connection is 100Mb/10Mb + * #MSS_MAC_LINK_STATUS_FDX - Connection is full/half duplex + * @see MAC_auto_setup_link() + */ +int32_t +MSS_MAC_link_status +( + void +) +{ + uint32_t link; + + configASSERT( MAC_test_instance() == MAC_OK ); + + link = PHY_link_status(); + if( link == MSS_MAC_LINK_STATUS_LINK ) { + link |= PHY_link_type(); + } + + return ((int32_t)link); +} + + +/***************************************************************************//** + * Setups the link between PHY and MAC and returns the status of connection. + * + * @return the logical OR of the following values: + * #MSS_MAC_LINK_STATUS_LINK - Link up/down + * #MSS_MAC_LINK_STATUS_100MB - Connection is 100Mb/10Mb + * #MSS_MAC_LINK_STATUS_FDX - Connection is full/half duplex + * @see MAC_link_status() + */ +int32_t +MSS_MAC_auto_setup_link +( + void +) +{ + int32_t link; + configASSERT( MAC_test_instance() == MAC_OK ); + + PHY_auto_negotiate(); + + link = MSS_MAC_link_status(); + + if( (link & MSS_MAC_LINK_STATUS_LINK) != 0u ) { + int32_t ret; + ret = MAC_stop_transmission(); + MAC_CHECK( ret == MAC_OK, ret ); + + ret = MAC_stop_receiving(); + MAC_CHECK( ret == MAC_OK, ret ); + MAC_BITBAND->CSR6_TTM = (uint32_t)((((uint32_t)link & MSS_MAC_LINK_STATUS_100MB) != 0u) ? 1u : 0u ); + MAC_BITBAND->CSR6_FD = (uint32_t)((((uint32_t)link & MSS_MAC_LINK_STATUS_FDX) != 0u) ? 1u : 1u ); + MAC_start_transmission(); + MAC_start_receiving(); + } + + return link; +} + + +/***************************************************************************//** + * Sets mac address. New address must be unicast. + * + * @param new_address Pointer to a MAC_instance_t structure + * @see MAC_get_mac_address() + */ +void +MSS_MAC_set_mac_address +( + const uint8_t *new_address +) +{ + configASSERT( MAC_test_instance() == MAC_OK ); + /* Check if the new address is unicast */ + configASSERT( (new_address[0]&1) == 0 ); + + MAC_memcpy( g_mss_mac.mac_address, new_address, 6u ); + + if((g_mss_mac.flags & FLAG_PERFECT_FILTERING) != 0u ) { + int32_t a; + /* set unused filters to the new mac address */ + for( a=14*6; a>=0; a-=6 ) { + if( (g_mss_mac.mac_filter_data[a] & 1u) != 0u ) { + /* Filters with multicast addresses are used */ + a = -1; + } else { + MAC_memcpy( &(g_mss_mac.mac_filter_data[a]), + g_mss_mac.mac_address, 6u ); + } + } + } + + MAC_send_setup_frame(); +} + + +/***************************************************************************//** + * Returns mac address. + * + * @param address Pointer to receive the MAC address + * @see MAC_set_mac_address() + */ +void +MSS_MAC_get_mac_address +( + uint8_t *address +) +{ + configASSERT( MAC_test_instance() == MAC_OK ); + + MAC_memcpy( address, g_mss_mac.mac_address, 6u ); +} + + +/***************************************************************************//** + * Sets mac address filters. Addresses must be multicast. + * + * @param filter_count number of addresses + * @param filters Pointer to addresses to be filtered + */ +void +MSS_MAC_set_mac_filters +( + uint16_t filter_count, + const uint8_t *filters +) +{ + configASSERT( MAC_test_instance() == MAC_OK ); + configASSERT( (filter_count==0) || (filters != NULL_buffer) ); + /* Check if the mac addresses is multicast */ + { + int32_t a; + for( a = 0u; a < filter_count; a++ ) { + configASSERT( (filters[a*6]&1) == 1 ); + } + } + + if( filter_count <= 15 ){ + int32_t a; + g_mss_mac.flags |= FLAG_PERFECT_FILTERING; + + /* copy new filters */ + MAC_memcpy( g_mss_mac.mac_filter_data, filters, (uint32_t)(filter_count*6)); + + /* set unused filters to our mac address */ + for( a=filter_count; a<15; a++ ) { + MAC_memcpy( &(g_mss_mac.mac_filter_data[a*6]), + g_mss_mac.mac_address, 6 ); + } + } else { + int32_t a,b; + uint32_t hash; + + g_mss_mac.flags &= ~FLAG_PERFECT_FILTERING; + + /* reset hash table */ + MAC_memset( g_mss_mac.mac_filter_data, 0u, 64u ); + + for( a=0, b=0; 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 +) +{ + configASSERT( MAC_test_instance() == MAC_OK ); + + /* disable tx and rx interrupts */ + MAC_BITBAND->CSR7_RIE = 0u; + MAC_BITBAND->CSR7_TIE = 0u; + + g_mss_mac.listener = listener; + + if( listener != NULL_callback ) { + /* enable tx and rx interrupts */ + MAC_BITBAND->CSR7_RIE = 1u; + MAC_BITBAND->CSR7_TIE = 1u; + } +} + + +/***************************************************************************//** + * Returns description of last error. + * + * @param instance Pointer to a MAC_instance_t structure + * @return A string describing the error. This string must not be + * modified by the application. + * #MAC_WRONG_PARAMETER if instance is null or hasn't been + * initialized. + */ +const int8_t* +MSS_MAC_last_error +( + void +) +{ + int8_t error_msg_nb; + const int8_t* returnvalue; + + configASSERT( MAC_test_instance() == MAC_OK ); + + error_msg_nb = -(g_mss_mac.last_error); + if( error_msg_nb >= ERROR_MESSAGE_COUNT ) { + returnvalue = unknown_error; + } else { + returnvalue = ErrorMessages[error_msg_nb]; + } + return returnvalue; +} + + +/***************************************************************************//** + * Returns statistics counter of stat_id identifier. + * + * @param instance Pointer to a MAC_instance_t structure + * @param stat_id Identifier of statistics counter. + * @return Statistics counter of stat_id identifier. + * On error returns 0. + */ +uint32_t +MSS_MAC_get_statistics +( + mss_mac_statistics_id_t stat_id +) +{ + uint32_t returnval = 0u; + configASSERT( MAC_test_instance() == MAC_OK ); + + switch( stat_id ) { + case MSS_MAC_RX_INTERRUPTS: + returnval = g_mss_mac.statistics.rx_interrupts; + break; + case MSS_MAC_RX_FILTERING_FAIL: + returnval = g_mss_mac.statistics.rx_filtering_fail; + break; + case MSS_MAC_RX_DESCRIPTOR_ERROR: + returnval = g_mss_mac.statistics.rx_descriptor_error; + break; + case MSS_MAC_RX_RUNT_FRAME: + returnval = g_mss_mac.statistics.rx_runt_frame; + break; + case MSS_MAC_RX_NOT_FIRST: + returnval = g_mss_mac.statistics.rx_not_first; + break; + case MSS_MAC_RX_NOT_LAST: + returnval = g_mss_mac.statistics.rx_not_last; + break; + case MSS_MAC_RX_FRAME_TOO_LONG: + returnval = g_mss_mac.statistics.rx_frame_too_long; + break; + case MSS_MAC_RX_COLLISION_SEEN: + returnval = g_mss_mac.statistics.rx_collision_seen; + break; + case MSS_MAC_RX_CRC_ERROR: + returnval = g_mss_mac.statistics.rx_crc_error; + break; + case MSS_MAC_RX_FIFO_OVERFLOW: + returnval = g_mss_mac.statistics.rx_fifo_overflow; + break; + case MSS_MAC_RX_MISSED_FRAME: + returnval = g_mss_mac.statistics.rx_missed_frame; + break; + case MSS_MAC_TX_INTERRUPTS: + returnval = g_mss_mac.statistics.tx_interrupts; + break; + case MSS_MAC_TX_LOSS_OF_CARRIER: + returnval = g_mss_mac.statistics.tx_loss_of_carrier; + break; + case MSS_MAC_TX_NO_CARRIER: + returnval = g_mss_mac.statistics.tx_no_carrier; + break; + case MSS_MAC_TX_LATE_COLLISION: + returnval = g_mss_mac.statistics.tx_late_collision; + break; + case MSS_MAC_TX_EXCESSIVE_COLLISION: + returnval = g_mss_mac.statistics.tx_excessive_collision; + break; + case MSS_MAC_TX_COLLISION_COUNT: + returnval = g_mss_mac.statistics.tx_collision_count; + break; + case MSS_MAC_TX_UNDERFLOW_ERROR: + returnval = g_mss_mac.statistics.tx_underflow_error; + break; + default: + break; + } + + return returnval; +} + + +/**************************** INTERNAL FUNCTIONS ******************************/ + +/***************************************************************************//** + * Checks if instace is valid. + */ +static int32_t +MAC_test_instance +( + void +) +{ + uint32_t val1; + uint32_t val2; + int32_t retval = MAC_WRONG_PARAMETER; + + val1 = MAC->CSR3; + val2 = MAC->CSR4; + + if( (&g_mss_mac != NULL_instance) && + ((g_mss_mac.flags & FLAG_MAC_INIT_DONE) != 0u) && + ( val1 == (uint32_t)g_mss_mac.rx_descriptors) && + (val2 == (uint32_t)g_mss_mac.tx_descriptors ) ) + { + retval = MAC_OK; + } + return retval; +} + +/***************************************************************************//** + * Prepares current rx descriptor for receiving. + */ +void +MSS_MAC_prepare_rx_descriptor +( + void +) +{ + uint32_t desc; + + /* update counters */ + desc = g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0; + if( (desc & RDES0_FF) != 0u ) { + g_mss_mac.statistics.rx_filtering_fail++; + } + if( (desc & RDES0_DE) != 0u ) { + g_mss_mac.statistics.rx_descriptor_error++; + } + if( (desc & RDES0_RF) != 0u ) { + g_mss_mac.statistics.rx_runt_frame++; + } + if( (desc & RDES0_FS) == 0u ) { + g_mss_mac.statistics.rx_not_first++; + } + if( (desc & RDES0_LS) == 0u ) { + g_mss_mac.statistics.rx_not_last++; + } + if( (desc & RDES0_TL) != 0u ) { + g_mss_mac.statistics.rx_frame_too_long++; + } + if( (desc & RDES0_CS) != 0u ) { + g_mss_mac.statistics.rx_collision_seen++; + } + if( (desc & RDES0_CE) != 0u ) { + g_mss_mac.statistics.rx_crc_error++; + } + + desc = MAC->CSR8; + g_mss_mac.statistics.rx_fifo_overflow += + (desc & (CSR8_OCO_MASK|CSR8_FOC_MASK)) >> CSR8_FOC_SHIFT; + g_mss_mac.statistics.rx_missed_frame += + (desc & (CSR8_MFO_MASK|CSR8_MFC_MASK)); + + /* Give ownership of descriptor to the MAC */ + g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 = + RDES0_OWN; + g_mss_mac.rx_desc_index = (g_mss_mac.rx_desc_index + 1u) % RX_RING_SIZE; + + /* Start receive */ + MAC_start_receiving(); +} + + +/***************************************************************************//** + * Prepares a setup frame and sends it to MAC. + * This function is blocking. + * @return #MAC_OK if everything is ok. + * #MAC_TIME_OUT if timed out before packet send. + */ +static int32_t +MAC_send_setup_frame +( + void +) +{ + volatile MAC_descriptor_t descriptor; + uint8_t frame_data[192]; + uint8_t *data; + int32_t a,b,c,d; + int32_t ret; + + /* prepare descriptor */ + descriptor.descriptor_0 = TDES0_OWN; + descriptor.descriptor_1 = TDES1_SET | TDES1_TER | + (sizeof(frame_data) << TDES1_TBS1_OFFSET); + + if( (g_mss_mac.flags & FLAG_PERFECT_FILTERING) == 0u ) { + descriptor.descriptor_1 |= TDES1_FT0; + } + + descriptor.buffer_1 = (uint32_t)frame_data; + descriptor.buffer_2 = 0u; + + /* prepare frame */ + if( (g_mss_mac.flags & FLAG_PERFECT_FILTERING) != 0u ) { + b = 0; + d = 12; + c = 90; + } else { + b = 156; + d = 0; + c = 64; + } + + data = g_mss_mac.mac_address; + frame_data[b] = data[0]; + frame_data[b+1] = data[1]; + frame_data[b+4] = data[2]; + frame_data[b+5] = data[3]; + frame_data[b+8] = data[4]; + frame_data[b+9] = data[5]; + + data = g_mss_mac.mac_filter_data; + for( a = 0; a < c; ) { + frame_data[d] = data[a++]; + frame_data[d+1] = data[a++]; + frame_data[d+4] = data[a++]; + frame_data[d+5] = data[a++]; + frame_data[d+8] = data[a++]; + frame_data[d+9] = data[a++]; + d += 12; + } + + /* Stop transmission */ + ret = MAC_stop_transmission(); + configASSERT( ret == MAC_OK ); + + ret = MAC_stop_receiving(); + configASSERT( ret == MAC_OK ); + + /* Set descriptor */ + MAC->CSR4 = (uint32_t)&descriptor; + + /* Start transmission */ + MAC_start_transmission(); + + /* Wait until transmission over */ + ret = MAC_OK; + MAC_set_time_out( (uint32_t)SETUP_FRAME_TIME_OUT ); + + while( (((MAC->CSR5 & CSR5_TS_MASK) >> CSR5_TS_SHIFT) != + CSR5_TS_SUSPENDED) && (MAC_OK == ret) ) + { + /* transmit poll demand */ + MAC->CSR1 = 1u; + if( MAC_get_time_out() == 0u ) { + ret = MAC_TIME_OUT; + } + } + + MAC_CHECK( MAC_stop_transmission() == MAC_OK, MAC_FAIL ); + + /* Set tx descriptor */ + MAC->CSR4 = (uint32_t)g_mss_mac.tx_descriptors; + + /* Start receiving and transmission */ + MAC_start_receiving(); + MAC_start_transmission(); + + return ret; +} + + +/***************************************************************************//** + * Stops transmission. + * Function will wait until transmit operation enters stop state. + * + * @return #MAC_OK if everything is ok. + * #MAC_TIME_OUT if timed out. + */ +static int32_t +MAC_stop_transmission +( + void +) +{ + int32_t retval = MAC_OK; + MAC_set_time_out( (uint16_t)STATE_CHANGE_TIME_OUT ); + + while( (((MAC->CSR5 & CSR5_TS_MASK) >> CSR5_TS_SHIFT) != + CSR5_TS_STOPPED) && (retval == MAC_OK) ) + { + MAC_BITBAND->CSR6_ST = 0u; + if( MAC_get_time_out() == 0u ) { + retval = MAC_TIME_OUT; + } + } + return retval; +} + + +/***************************************************************************//** + * Starts transmission. + */ +static void +MAC_start_transmission +( + void +) +{ + MAC_BITBAND->CSR6_ST = 1u; +} + + +/***************************************************************************//** + * Stops transmission. + * Function will wait until transmit operation enters stop state. + * + * @return #MAC_OK if everything is ok. + * #MAC_TIME_OUT if timed out. + */ +static int32_t +MAC_stop_receiving +( + void +) +{ + int32_t retval = MAC_OK; + MAC_set_time_out( (uint16_t)STATE_CHANGE_TIME_OUT ); + + while( (((MAC->CSR5 & CSR5_RS_MASK) >> CSR5_RS_SHIFT) != CSR5_RS_STOPPED) + && (retval == MAC_OK) ) + { + MAC_BITBAND->CSR6_SR = 0u; + if( MAC_get_time_out() == 0u ) { + retval = MAC_TIME_OUT; + } + } + + return retval; +} + + +/***************************************************************************//** + * Starts transmission. + */ +static void +MAC_start_receiving +( + void +) +{ + MAC_BITBAND->CSR6_SR = 1u; +} + + +/***************************************************************************//** + * Dismisses bad frames. + * + * @return dismissed frame count. + */ +static int32_t +MAC_dismiss_bad_frames +( + void +) +{ + int32_t dc = 0; + int8_t cont = 1; + + if( MAC_BITBAND->CSR6_PB != 0u ) { + /* User wants bad frames too, don't dismiss anything */ + cont = 0; + } + + while( ( (g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 & + RDES0_OWN) == 0u) && (cont == 1) ) /* Host owns this descriptor */ + { + /* check error summary */ + if( (g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 & + (RDES0_ES | RDES0_LS | RDES0_FS)) != (RDES0_LS | RDES0_FS) ) + { + MSS_MAC_prepare_rx_descriptor(); + dc++; + } + else + { + cont = 0; + } + } + + return dc; +} + +/***************************************************************************//** + * Sets time out value. + * #MAC_get_time_out must be called frequently to make time out value updated. + * Because of user may not be using ISR, we can not update time out in ISR. + * + * @time_out time out value in milli seconds. + * Must be smaller than 0x01000000. + */ +static void +MAC_set_time_out +( + uint32_t time_out +) +{ + g_mss_mac.time_out_value = (time_out * 122u) / 10u; + + g_mss_mac.last_timer_value = (uint16_t)( MAC->CSR11 & CSR11_TIM_MASK ); +} + +/***************************************************************************//** + * Returns time out value. + * + * @return timer out value in milli seconds. + */ +static uint32_t +MAC_get_time_out +( + void +) +{ + uint32_t timer; + uint32_t time = 0u; + + timer = ( MAC->CSR11 & CSR11_TIM_MASK ); + + if( timer > g_mss_mac.last_timer_value ) { + time = 0x0000ffffUL; + } + time += g_mss_mac.last_timer_value - timer; + + if( MAC_BITBAND->CSR6_TTM == 0u ) { + time *= 10u; + } + if( g_mss_mac.time_out_value <= time ){ + g_mss_mac.time_out_value = 0u; + } else { + g_mss_mac.time_out_value -= time; + } + + g_mss_mac.last_timer_value = (uint16_t)timer; + + return ((g_mss_mac.time_out_value * 10u) / 122u); +} + +/***************************************************************************//** + * Fills the first n bytes of the memory area pointed to by s with the constant + * byte c. + */ +static void MAC_memset(uint8_t *s, uint8_t c, uint32_t n) +{ + uint8_t *sb = s; + + while( n > 0u ) { + n--; + sb[n] = c; + } +} + +/***************************************************************************//** + * Fills all fields of MAC_instance_t with c. + * + * @return a pointer to the given MAC_instance_t s. + */ +static void MAC_memset_All(MAC_instance_t *s, uint32_t c) +{ + int32_t count; + s->base_address = (addr_t)c; + s->flags = (uint8_t)c; + s->last_error = (int8_t)c; + s->last_timer_value = (uint16_t)c; + s->listener = NULL_callback; + MAC_memset( s->mac_address, (uint8_t)c, 6u ); + MAC_memset( s->mac_filter_data, (uint8_t)c, 90u ); + s->phy_address = (uint8_t)c; +// for(count = 0; 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]; + } +} + +void MSS_MAC_TxBufferCompleted( void ) +{ +unsigned char *pxTransmittedBuffer; + + /* Was it the second transmission that has completed? */ + if( ( g_mss_mac.tx_descriptors[ 1 ].descriptor_0 & TDES0_OWN ) == 0UL ) + { + pxTransmittedBuffer = ( unsigned char * ) g_mss_mac.tx_descriptors[ 1 ].buffer_1; + + /* The buffer has been transmitted and is no longer in use. */ + MAC_release_buffer( pxTransmittedBuffer ); + } + else + { +// configASSERT( 0 ); + } +} + +static unsigned char *MAC_obtain_buffer( void ) +{ +long lIndex; +unsigned char *pcReturn = NULL; + + /* Find and return the address of a buffer that is not being used. Mark + the buffer as now in use. */ + for( lIndex = 0; lIndex < macNUM_BUFFERS; lIndex++ ) + { + if( ucMACBufferInUse[ lIndex ] == pdFALSE ) + { + pcReturn = &( ucMACBuffers[ lIndex ][ 0 ] ); + ucMACBufferInUse[ lIndex ] = pdTRUE; + break; + } + } + + configASSERT( pcReturn ); + return pcReturn; +} + +void MAC_release_buffer( unsigned char *pucBufferToRelease ) +{ +long lIndex; + + /* uip_buf is going to point to a different buffer - first ensure the buffer + it is currently pointing to is marked as being free again. */ + for( lIndex = 0; lIndex < macNUM_BUFFERS; lIndex++ ) + { + if( pucBufferToRelease == &( ucMACBuffers[ lIndex ][ 0 ] ) ) + { + /* This is the buffer in use, mark it as being free. */ + ucMACBufferInUse[ lIndex ] = pdFALSE; + break; + } + } + + configASSERT( lIndex < macNUM_BUFFERS ); +} + + + +#ifdef __cplusplus +} +#endif + +/******************************** END OF FILE *********************************/ + diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac.h new file mode 100644 index 000000000..0757105a5 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac.h @@ -0,0 +1,585 @@ +/***************************************************************************//** + * @file + * SmartFusion MSS Ethernet MAC header file. + * + * (c) Copyright 2007 Actel Corporation + * + * SVN $Revision: 2364 $ + * SVN $Date: 2010-03-01 17:58:41 +0000 (Mon, 01 Mar 2010) $ + * + *******************************************************************************/ + +#ifndef __MSS_ETHERNET_MAC_H +#define __MSS_ETHERNET_MAC_H 1 + +#include + +#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 from the uIP stack to the Ethernet Controller. + The MSS_MAC_tx_packet() function is used to send a packet to the MSS Ethernet + MAC. This function writes uip_len bytes of the packet contained in uip_buf into + the transmit FIFO and then activates the transmitter for this packet. If space + is available in the FIFO, the function will return once pac_len bytes of the + packet have been placed into the FIFO and the transmitter has been started. + This function will not wait for the transmission to complete. + + @return + The function returns zero if a timeout occurs otherwise it returns size of the packet. + + @see MAC_rx_packet() + */ + +int32_t +MSS_MAC_tx_packet +( + unsigned short usLength +); + +/***************************************************************************//** + * Returns available packet's size. + * + * @return Size of packet, bigger than 0, if a packet is available, + * if not, returns 0. + * @see MAC_rx_packet() + */ +int32_t +MSS_MAC_rx_pckt_size +( + void +); + + + +/***************************************************************************//** + * Prepares the RX descriptor for receiving packets. + * + * @return void + * @see MAC_rx_packet() + */ +void +MSS_MAC_prepare_rx_descriptor +( + void +); + +/***************************************************************************//** + * Receives a packet from the Ethernet Controller into the uIP stack. + * This function reads a packet from the receive FIFO of the controller and + * places it into uip_buf. + + * @return Size of packet if packet fits in uip_buf. + * 0 if there is no received packet. + * @see MAC_rx_pckt_size() + * @see MAC_tx_packet() + */ +int32_t +MSS_MAC_rx_packet +( + void +); + + +/***************************************************************************//** + Receives a packet from the Ethernet Controller. + The MSS_MAC_rx_packet_ptrset() function is very similar to the MSS_MAC_rx_packet() + function, in that it receives data from the MSS Ethernet MAC. The difference + is that it sets pacData to point to the memory buffer where the MSS Ethernet + MAC copied the received packet instead of copying the received packet into a + buffer provided by the application. After this function is called and data is + used by the user application or copied to another buffer, the + MSS_MAC_prepare_rx_descriptor() function must be called to free up the receive + memory buffer used by the MSS Ethernet MAC + + @param pacData + The pacData parameter is a pointer to a memory buffer pointer. The uint8_t + pointer pointed to by the pacData parameter will contain the address of the + memory buffer containing the received packet after this function returns. The + value of pacData is only valid if the return value is larger than zero, + indicating that a packet was received. + + @param time_out + The time_out parameter is the timeout value for the transmission in milliseconds. + The time_out parameter value can be one of the following values: + • Unsigned integer greater than 0 and less than 0x01000000 + • MSS_MAC_BLOCKING – there will be no timeout. + • MSS_MAC_NONBLOCKING – the function will return immediately if no packets + have been received. + + @return + The function returns the size of the packet if the packet fits in pacData. + Returns zero if there is no received packet. + + @see MAC_rx_pckt_size() + @see MAC_tx_packet() + */ +int32_t +MSS_MAC_rx_packet_ptrset +( + uint8_t **pacData, + uint32_t time_out +); + +/***************************************************************************//** + * Returns the status of connection by reading it from the PHY. + * + * @return the logical OR of the following values: + * #MSS_MAC_LINK_STATUS_LINK - Link up/down + * #MSS_MAC_LINK_STATUS_100MB - Connection is 100Mb/10Mb + * #MSS_MAC_LINK_STATUS_FDX - Connection is full/half duplex + * @see MAC_auto_setup_link() + */ +int32_t +MSS_MAC_link_status +( + void +); + + +/***************************************************************************//** + * Setups the link between PHY and MAC and returns the status of connection. + * + * @return the logical OR of the following values: + * #MSS_MAC_LINK_STATUS_LINK - Link up/down + * #MSS_MAC_LINK_STATUS_100MB - Connection is 100Mb/10Mb + * #MSS_MAC_LINK_STATUS_FDX - Connection is full/half duplex + * @see MAC_link_status() + */ +int32_t +MSS_MAC_auto_setup_link +( + void +); + + +/***************************************************************************//** + * Sets mac address. + * + * @param new_address Pointer to then new address value (6 bytes of data) + * @see MAC_get_mac_address() + */ +void +MSS_MAC_set_mac_address +( + const uint8_t *new_address +); + + +/***************************************************************************//** + * Returns mac address. + * + * @param address Pointer to the parameter to receive the MAC address. + * @see MAC_set_mac_address() + */ +void +MSS_MAC_get_mac_address +( + uint8_t *address +); + + +/***************************************************************************//** + * Sets mac address filters. + * If less than 15 addresses are subscribed, system works on perfect filtering mode + * else system works in hash table mode + * + * @param filter_count number of addresses + * @param filters Pointer to addresses to be filtered + */ +void +MSS_MAC_set_mac_filters +( + uint16_t filter_count, + const uint8_t *filters +); + +/***************************************************************************//** + * Sets MAC event listener. + * Sets the given event listener function to be triggered inside MAC_isr(). + * Assigning NULL pointer as the listener function will disable it. + * + * @param listener function pointer to a MSS_MAC_callback_t function + * @see MAC_isr() + */ +void +MSS_MAC_set_callback +( + MSS_MAC_callback_t listener +); + + +/***************************************************************************//** + * Returns description of latest error happened. + * + * @return A string describing the error. This string must not be + * modified by the application. + */ +const int8_t* +MSS_MAC_last_error +( + void +); + + +/***************************************************************************//** + * Returns statistics counter of stat_id identifier. + * + * @param stat_id Identifier of statistics counter. + * @return Statistics counter of stat_id identifier. + * On error returns 0. + */ +uint32_t +MSS_MAC_get_statistics +( + mss_mac_statistics_id_t stat_id +); + +/* + * Ensure uip_buf is pointing to a valid and free buffer before any transmissions + * initiated by the uIP stack occur. + */ +unsigned char *MSS_MAC_GetTxDescriptor( void ); + +/* + * A buffer is no longer required by the application. Hand it back to the + * control of the MAC hardware. + */ +void MSS_MAC_ReleaseBuffer( unsigned char *pucBuffer ); + +/* + * The double Tx has completed. Hand back the Tx buffer to the control of + * the MAC hardware. + */ +void MSS_MAC_TxBufferCompleted( void ); +#ifdef __cplusplus +} +#endif + +#endif /* __MSS_ETHERNET_MAC_H */ + diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_conf.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_conf.h new file mode 100644 index 000000000..ac144b36b --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_conf.h @@ -0,0 +1,43 @@ +/***************************************************************************//** + * @file + * SmartFusion MSS Ethenet MAC configuration header file. + * + * (c) Copyright 2007 Actel Corporation + * + * SVN $Revision: 2299 $ + * SVN $Date: 2010-02-24 21:21:12 +0000 (Wed, 24 Feb 2010) $ + *******************************************************************************/ +#ifndef __MSS_ETHERNET_MAC_CONF_H +#define __MSS_ETHERNET_MAC_CONF_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Default MAC address + */ +#define DEFAULT_MAC_ADDRESS configMAC_ADDR0, configMAC_ADDR1, configMAC_ADDR2, configMAC_ADDR3, configMAC_ADDR4, configMAC_ADDR5 +#define BROADCAST_MAC_ADDRESS 0xFFu,0xFFu,0xFFu,0xFFu,0xFFu,0xFFu + +/** + * Descriptor byte ordering mode. + * 1 - Big-endian mode used for data descriptors
+ * 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_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_desc.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_desc.h new file mode 100644 index 000000000..dc697f11a --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_desc.h @@ -0,0 +1,346 @@ +/***************************************************************************//** + * @file + * SmartFusion MSS Ethernet MAC internal defines header file. + * + * (c) Copyright 2007 Actel Corporation + * + * SVN $Revision: 2299 $ + * SVN $Date: 2010-02-24 21:21:12 +0000 (Wed, 24 Feb 2010) $ + *******************************************************************************/ +#ifndef __MSS_ETHERNET_MAC_DESC_H +#define __MSS_ETHERNET_MAC_DESC_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * Receive descriptor bits + */ + +/***************************************************************************//** + * Ownership bit. + * 1 - Core10/100 owns the descriptor.
+ * 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_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_regs.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_regs.h new file mode 100644 index 000000000..d54c6e94f --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_regs.h @@ -0,0 +1,1201 @@ +/***************************************************************************//** + * @file + * SmartFusion MSS Ethernet MAC registers. + * + * (c) Copyright 2007 Actel Corporation + * + * IP core registers definitions. This file contains the definitions required + * for accessing the IP core through the hardware abstraction layer (HAL). + * This file was automatically generated, using "get_header.exe" version 0.4.0, + * from the IP-XACT description for: + * + * + * SVN $Revision: 2364 $ + * SVN $Date: 2010-03-01 17:58:41 +0000 (Mon, 01 Mar 2010) $ + * + *******************************************************************************/ +#ifndef MSS_ETHERNET_MAC_REGISTERS_H_ +#define MSS_ETHERNET_MAC_REGISTERS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../../CMSIS/a2fxxxm3.h" +#include "mss_ethernet_mac.h" +#include "mss_ethernet_mac_user_cfg.h" + +typedef uint32_t addr_t; + + +/***************************************************************************//** + * Descriptor structure + */ +typedef struct { + volatile uint32_t descriptor_0; + volatile uint32_t descriptor_1; + volatile uint32_t buffer_1; + volatile uint32_t buffer_2; +} MAC_descriptor_t; + + +/***************************************************************************//** + * There should be one instance of this structure for each instance of + * the MAC in your system. MSS_MAC_init routine initializes this structure. + * It is used to identify the various MACs in your system and an initilized + * MAC instance's structure should be passed as first parameter to MAC functions + * to identify which MAC should perform the requested operation. + * Software using the MAC driver should only need to create one single + * instance of this data structure for each MAC hardware instance in + * the system. Using MAC_get_configuration routine, latest status of the driver + * may be read by receiving its flags field, similarly MAC_configure routine lets + * you modify some of these flags. + */ +typedef struct { + addr_t base_address; /**< Register base address of the driver*/ + uint8_t flags; /**< Configuration of the driver*/ + int8_t last_error; /**< Index of last error happened inside the driver*/ + uint8_t mac_address[6]; /**< MAC address of the drived instance*/ + uint8_t mac_filter_data[90]; /**< MAC filter data, 15 addresses to be used for + received data filtering*/ + uint16_t last_timer_value; /**< Last read value of timer */ + uint32_t time_out_value; /**< Time out value */ + MSS_MAC_callback_t listener; /**< Pointer to the call-back function to be triggered + when a package is received*/ + + /* transmit related info: */ + uint32_t tx_desc_index; /**< index of the transmit descriptor getting used*/ +// uint8_t tx_buffers[TX_RING_SIZE][MSS_TX_BUFF_SIZE];/**< array of transmit buffers*/ + MAC_descriptor_t tx_descriptors[TX_RING_SIZE];/**< array of transmit descriptors*/ + + /* receive related info: */ + uint32_t rx_desc_index; /**< index of the receive descriptor getting used*/ +// uint8_t rx_buffers[RX_RING_SIZE][MSS_RX_BUFF_SIZE+4];/**< array of receive buffers*/ + MAC_descriptor_t rx_descriptors[RX_RING_SIZE];/**< array of receive descriptors*/ + + uint8_t phy_address; /**< MII address of the connected PHY*/ + + struct { + uint32_t rx_interrupts; /**< Number of receive interrupts occurred.*/ + uint32_t rx_filtering_fail; /**< Number of received frames which did not pass + the address recognition process.*/ + uint32_t rx_descriptor_error; /**< Number of occurrences of; no receive buffer was + available when trying to store the received data.*/ + uint32_t rx_runt_frame; /**< Number of occurrences of; the frame is damaged by + a collision or by a premature termination before + the end of a collision window.*/ + uint32_t rx_not_first; /**< Number of occurrences of; start of the frame is + not the first descriptor of a frame.*/ + uint32_t rx_not_last; /**< Number of occurrences of; end of the frame is not + the first descriptor of a frame.*/ + uint32_t rx_frame_too_long; /**< Number of occurrences of; a current frame is + longer than maximum size of 1,518 bytes, as specified + by 802.3.*/ + uint32_t rx_collision_seen; /**< Number of occurrences of; a late collision was seen + (collision after 64 bytes following SFD).*/ + uint32_t rx_crc_error; /**< Number of occurrences of; a CRC error has occurred + in the received frame.*/ + uint32_t rx_fifo_overflow; /**< Number of frames not accepted due to the receive + FIFO overflow.*/ + uint32_t rx_missed_frame; /**< Number of frames not accepted due to the + unavailability of the receive descriptor.*/ + + uint32_t tx_interrupts; /**< Number of transmit interrupts occurred.*/ + uint32_t tx_loss_of_carrier; /**< Number of occurrences of; a loss of the carrier + during a transmission.*/ + uint32_t tx_no_carrier; /**< Number of occurrences of; the carrier was not asserted + by an external transceiver during the transmission.*/ + uint32_t tx_late_collision; /**< Number of occurrences of; a collision was detected + after transmitting 64 bytes.*/ + uint32_t tx_excessive_collision;/**< Number of occurrences of; the transmission was + aborted after 16 retries.*/ + uint32_t tx_collision_count; /**< Number of collisions occurred.*/ + uint32_t tx_underflow_error; /**< Number of occurrences of; the FIFO was empty during + the frame transmission.*/ + } statistics; +} MAC_instance_t __attribute__((packed)); + + +/*------------------------------------------------------------------------------ + * + */ +typedef struct +{ + uint32_t CSR0_SWR; + uint32_t CSR0_BAR; + uint32_t CSR0_DSL[5]; + uint32_t CSR0_BLE; + uint32_t CSR0_PBL[6]; + uint32_t CSR0_RESERVED0[3]; + uint32_t CSR0_TAP[3]; + uint32_t CSR0_DBO; + uint32_t CSR0_RESERVED1[11]; + + uint32_t MAC_CSR_RESERVED0[32]; + + uint32_t CSR1[32]; + + uint32_t MAC_CSR_RESERVED1[32]; + + uint32_t CSR2[32]; + + uint32_t MAC_CSR_RESERVED2[32]; + + uint32_t CSR3[32]; + + uint32_t MAC_CSR_RESERVED3[32]; + + uint32_t CSR4[32]; + + uint32_t MAC_CSR_RESERVED4[32]; + + uint32_t CSR5_TI; + uint32_t CSR5_TPS; + uint32_t CSR5_TU; + uint32_t CSR5_RESERVED0[2]; + uint32_t CSR5_UNF; + uint32_t CSR5_RI; + uint32_t CSR5_RU; + uint32_t CSR5_RPS; + uint32_t CSR5_RESERVED1; + uint32_t CSR5_ETI; + uint32_t CSR5_GTE; + uint32_t CSR5_RESERVED2[2]; + uint32_t CSR5_ERI; + uint32_t CSR5_AIS; + uint32_t CSR5_NIS; + uint32_t CSR5_RS[3]; + uint32_t CSR5_TS[3]; + uint32_t CSR5_RESERVED3[9]; + + uint32_t MAC_CSR_RESERVED5[32]; + + uint32_t CSR6_HP; + uint32_t CSR6_SR; + uint32_t CSR6_HO; + uint32_t CSR6_PB; + uint32_t CSR6_IF; + uint32_t CSR6_RESERVED0; + uint32_t CSR6_PR; + uint32_t CSR6_PM; + uint32_t CSR6_RESERVED1; + uint32_t CSR6_FD; + uint32_t CSR6_RESERVED2[3]; + uint32_t CSR6_ST; + uint32_t CSR6_TR[2]; + uint32_t CSR6_RESERVED3[5]; + uint32_t CSR6_SF; + uint32_t CSR6_TTM; + uint32_t CSR6_RESERVED4[7]; + uint32_t CSR6_RA; + uint32_t CSR6_RESERVED5; + + uint32_t MAC_CSR_RESERVED6[32]; + + uint32_t CSR7_TIE; + uint32_t CSR7_TSE; + uint32_t CSR7_TUE; + uint32_t CSR7_RESERVED0[2]; + uint32_t CSR7_UNE; + uint32_t CSR7_RIE; + uint32_t CSR7_RUE; + uint32_t CSR7_RSE; + uint32_t CSR7_RESERVED1; + uint32_t CSR7_ETE; + uint32_t CSR7_GTE; + uint32_t CSR7_RESERVED2[2]; + uint32_t CSR7_ERE; + uint32_t CSR7_AIE; + uint32_t CSR7_NIE; + uint32_t CSR7[15]; + + uint32_t MAC_CSR_RESERVED7[32]; + + uint32_t CSR8[32]; + + uint32_t MAC_CSR_RESERVED8[32]; + + uint32_t CSR9_SCS; + uint32_t CSR9_SCLK; + uint32_t CSR9_SDI; + uint32_t CSR9_SDO; + uint32_t CSR9_RESERVED0[12]; + uint32_t CSR9_MDC; + uint32_t CSR9_MDO; + uint32_t CSR9_MDEN; + uint32_t CSR9_MDI; + uint32_t CSR9_RESERVED1[12]; + + uint32_t MAC_CSR_RESERVED9[32]; + + uint32_t CSR10[32]; + + uint32_t MAC_CSR_RESERVED10[32]; + + uint32_t CSR11_TIM[16]; + uint32_t CSR11_CON; + uint32_t CSR11_NRP[3]; + uint32_t CSR11_RT[4]; + uint32_t CSR11_NTP[3]; + uint32_t CSR11_TT[4]; + uint32_t CSR11_CS; +} MAC_BitBand_TypeDef; + +#define MAC_BITBAND ((MAC_BitBand_TypeDef *) BITBAND_ADDRESS(MAC_BASE)) + +/******************************************************************************* + * CSR0 register: + *------------------------------------------------------------------------------ + * CSR0 - Bus Mode Register + */ +#define CSR0_REG_OFFSET 0x00 + +/*------------------------------------------------------------------------------ + * CSR0_DBO: + * DBO field of register CSR0. + *------------------------------------------------------------------------------ + * Descriptor byte ordering mode + */ +#define CSR0_DBO_OFFSET 0x00 +#define CSR0_DBO_MASK 0x00100000UL +#define CSR0_DBO_SHIFT 20 + +/* + * Allowed values for CSR0_DBO: + *------------------------------------------------------------------------------ + * LITTLEENDIAN: Little endian mode used for data descriptors + * BIGENDIAN: Big endian mode used for data descriptors + */ +#define LITTLEENDIAN 0u +#define BIGENDIAN 1u + +/*------------------------------------------------------------------------------ + * CSR0_TAP: + * TAP field of register CSR0. + *------------------------------------------------------------------------------ + * Transmit automatic polling + */ +#define CSR0_TAP_OFFSET 0x00 +#define CSR0_TAP_MASK 0x000E0000UL +#define CSR0_TAP_SHIFT 17 + +/* + * Allowed values for CSR0_TAP: + *------------------------------------------------------------------------------ + * TAP_DISABLED: TAP disabled + * TAP_819US: TAP 819/81.9us + * TAP_2450US: TAP 2450/245us + * TAP_5730US: TAP 5730/573us + * TAP_51_2US: TAP 51.2/5.12us + * TAP_102_4US: TAP 102.4/10.24us + * TAP_153_6US: TAP 156.6/15.26us + * TAP_358_4US: TAP 358.4/35.84us + */ +#define TAP_DISABLED 0x0 +#define TAP_819US 0x1 +#define TAP_2450US 0x2 +#define TAP_5730US 0x3 +#define TAP_51_2US 0x4 +#define TAP_102_4US 0x5 +#define TAP_153_6US 0x6 +#define TAP_358_4US 0x7 + +/*------------------------------------------------------------------------------ + * CSR0_PBL: + * PBL field of register CSR0. + *------------------------------------------------------------------------------ + * Programmable burst length + */ +#define CSR0_PBL_OFFSET 0x00 +#define CSR0_PBL_MASK 0x00003F00uL +#define CSR0_PBL_SHIFT 8 + +/*------------------------------------------------------------------------------ + * CSR0_BLE: + * BLE field of register CSR0. + *------------------------------------------------------------------------------ + * Big/little endian + */ +#define CSR0_BLE_OFFSET 0x00 +#define CSR0_BLE_MASK 0x00000080uL +#define CSR0_BLE_SHIFT 7 + +/*------------------------------------------------------------------------------ + * CSR0_DSL: + * DSL field of register CSR0. + *------------------------------------------------------------------------------ + * Descriptor skip length + */ +#define CSR0_DSL_OFFSET 0x00 +#define CSR0_DSL_MASK 0x0000007CuL +#define CSR0_DSL_SHIFT 2 + +/*------------------------------------------------------------------------------ + * CSR0_BAR: + * BAR field of register CSR0. + *------------------------------------------------------------------------------ + * Bus arbitration scheme + */ +#define CSR0_BAR_OFFSET 0x00 +#define CSR0_BAR_MASK 0x00000002uL +#define CSR0_BAR_SHIFT 1 + +/*------------------------------------------------------------------------------ + * CSR0_SWR: + * SWR field of register CSR0. + *------------------------------------------------------------------------------ + * Software reset + */ +#define CSR0_SWR_OFFSET 0x00 +#define CSR0_SWR_MASK 0x00000001uL +#define CSR0_SWR_SHIFT 0 + +/******************************************************************************* + * CSR1 register: + *------------------------------------------------------------------------------ + * CSR1 - Transmit Poll Demand Register + */ +#define CSR1_REG_OFFSET 0x08 + +/*------------------------------------------------------------------------------ + * CSR1_TPD3: + * TPD3 field of register CSR1. + *------------------------------------------------------------------------------ + * TPD(31..24) + */ +#define CSR1_TPD3_OFFSET 0x08 +#define CSR1_TPD3_MASK 0xFF000000uL +#define CSR1_TPD3_SHIFT 24 + +/*------------------------------------------------------------------------------ + * CSR1_TPD2: + * TPD2 field of register CSR1. + *------------------------------------------------------------------------------ + * TPD(23..16) + */ +#define CSR1_TPD2_OFFSET 0x08 +#define CSR1_TPD2_MASK 0x00FF0000uL +#define CSR1_TPD2_SHIFT 16 + +/*------------------------------------------------------------------------------ + * CSR1_TPD1: + * TPD1 field of register CSR1. + *------------------------------------------------------------------------------ + * TPD(15..8) + */ +#define CSR1_TPD1_OFFSET 0x08 +#define CSR1_TPD1_MASK 0x0000FF00uL +#define CSR1_TPD1_SHIFT 8 + +/*------------------------------------------------------------------------------ + * CSR1_TPD0: + * TPD0 field of register CSR1. + *------------------------------------------------------------------------------ + * TPD(7..0) + */ +#define CSR1_TPD0_OFFSET 0x08 +#define CSR1_TPD0_MASK 0x000000FFuL +#define CSR1_TPD0_SHIFT 0 + +/******************************************************************************* + * CSR2 register: + *------------------------------------------------------------------------------ + * CSR2 - Receive Poll Demand Register + */ +#define CSR2_REG_OFFSET 0x10 + +/*------------------------------------------------------------------------------ + * CSR2_RPD3: + * RPD3 field of register CSR2. + *------------------------------------------------------------------------------ + * RPD(31..24) + */ +#define CSR2_RPD3_OFFSET 0x10 +#define CSR2_RPD3_MASK 0xFF000000uL +#define CSR2_RPD3_SHIFT 24 + +/*------------------------------------------------------------------------------ + * CSR2_RPD2: + * RPD2 field of register CSR2. + *------------------------------------------------------------------------------ + * RPD(23..16) + */ +#define CSR2_RPD2_OFFSET 0x10 +#define CSR2_RPD2_MASK 0x00FF0000uL +#define CSR2_RPD2_SHIFT 16 + +/*------------------------------------------------------------------------------ + * CSR2_RPD1: + * RPD1 field of register CSR2. + *------------------------------------------------------------------------------ + * RPD(15..8) + */ +#define CSR2_RPD1_OFFSET 0x10 +#define CSR2_RPD1_MASK 0x0000FF00uL +#define CSR2_RPD1_SHIFT 8 + +/*------------------------------------------------------------------------------ + * CSR2_RPD0: + * RPD0 field of register CSR2. + *------------------------------------------------------------------------------ + * RPD(7..0) + */ +#define CSR2_RPD0_OFFSET 0x10 +#define CSR2_RPD0_MASK 0x000000FFuL +#define CSR2_RPD0_SHIFT 0 + +/******************************************************************************* + * CSR3 register: + *------------------------------------------------------------------------------ + * CSR3 - Receive Descriptor List Base Address Register + */ +#define CSR3_REG_OFFSET 0x18 + +/*------------------------------------------------------------------------------ + * CSR3_RLA3: + * RLA3 field of register CSR3. + *------------------------------------------------------------------------------ + * RLA(31..24) + */ +#define CSR3_RLA3_OFFSET 0x18 +#define CSR3_RLA3_MASK 0xFF000000uL +#define CSR3_RLA3_SHIFT 24 + +/*------------------------------------------------------------------------------ + * CSR3_RLA2: + * RLA2 field of register CSR3. + *------------------------------------------------------------------------------ + * RLA(23..16) + */ +#define CSR3_RLA2_OFFSET 0x18 +#define CSR3_RLA2_MASK 0x00FF0000uL +#define CSR3_RLA2_SHIFT 16 + +/*------------------------------------------------------------------------------ + * CSR3_RLA1: + * RLA1 field of register CSR3. + *------------------------------------------------------------------------------ + * RLA(15..8) + */ +#define CSR3_RLA1_OFFSET 0x18 +#define CSR3_RLA1_MASK 0x0000FF00uL +#define CSR3_RLA1_SHIFT 8 + +/*------------------------------------------------------------------------------ + * CSR3_RLA0: + * RLA0 field of register CSR3. + *------------------------------------------------------------------------------ + * RLA(7..0) + */ +#define CSR3_RLA0_OFFSET 0x18 +#define CSR3_RLA0_MASK 0x000000FFuL +#define CSR3_RLA0_SHIFT 0 + +/******************************************************************************* + * CSR4 register: + *------------------------------------------------------------------------------ + * CSR4 - Transmit Descriptor List Base Address Register + */ +#define CSR4_REG_OFFSET 0x20 + +/*------------------------------------------------------------------------------ + * CSR4_TLA3: + * TLA3 field of register CSR4. + *------------------------------------------------------------------------------ + * TLA(31..24) + */ +#define CSR4_TLA3_OFFSET 0x20 +#define CSR4_TLA3_MASK 0xFF000000uL +#define CSR4_TLA3_SHIFT 24 + +/*------------------------------------------------------------------------------ + * CSR4_TLA2: + * TLA2 field of register CSR4. + *------------------------------------------------------------------------------ + * TLA(23..16) + */ +#define CSR4_TLA2_OFFSET 0x20 +#define CSR4_TLA2_MASK 0x00FF0000uL +#define CSR4_TLA2_SHIFT 16 + +/*------------------------------------------------------------------------------ + * CSR4_TLA1: + * TLA1 field of register CSR4. + *------------------------------------------------------------------------------ + * TLA(15..8) + */ +#define CSR4_TLA1_OFFSET 0x20 +#define CSR4_TLA1_MASK 0x0000FF00uL +#define CSR4_TLA1_SHIFT 8 + +/*------------------------------------------------------------------------------ + * CSR4_TLA0: + * TLA0 field of register CSR4. + *------------------------------------------------------------------------------ + * TLA(7..0) + */ +#define CSR4_TLA0_OFFSET 0x20 +#define CSR4_TLA0_MASK 0x000000FFuL +#define CSR4_TLA0_SHIFT 0 + +/******************************************************************************* + * CSR5 register: + *------------------------------------------------------------------------------ + * CSR5 - Status Register + */ +#define CSR5_REG_OFFSET 0x28 +#define CSR5_INT_BITS (CSR5_NIS_MASK | CSR5_AIS_MASK | CSR5_ERI_MASK | \ + CSR5_GTE_MASK | CSR5_ETI_MASK | CSR5_RPS_MASK | CSR5_RU_MASK | \ + CSR5_RI_MASK | CSR5_UNF_MASK | CSR5_TU_MASK | CSR5_TPS_MASK | CSR5_TI_MASK) + +/*------------------------------------------------------------------------------ + * CSR5_TS: + * TS field of register CSR5. + *------------------------------------------------------------------------------ + * Transmit process state + */ +#define CSR5_TS_OFFSET 0x28 +#define CSR5_TS_MASK 0x00700000uL +#define CSR5_TS_SHIFT 20 + +/** 000 - Stopped; RESET or STOP TRANSMIT command issued. */ +#define CSR5_TS_STOPPED 0u +/** 001 - Running, fetching the transmit descriptor. */ +#define CSR5_TS_RUNNING_FD 1u +/** 010 - Running, waiting for end of transmission. */ +#define CSR5_TS_RUNNING_WT 2u +/** 011 - Running, transferring data buffer from host memory to FIFO. */ +#define CSR5_TS_RUNNING_TD 3u +/** 101 - Running, setup packet. */ +#define CSR5_TS_RUNNING_SP 5u +/** 110 - Suspended; FIFO underflow or unavailable descriptor. */ +#define CSR5_TS_SUSPENDED 6u +/** 111 - Running, closing transmit descriptor. */ +#define CSR5_TS_RUNNING_CD 7u + +/*------------------------------------------------------------------------------ + * CSR5_RS: + * RS field of register CSR5. + *------------------------------------------------------------------------------ + * Receive process state + */ +#define CSR5_RS_OFFSET 0x28 +#define CSR5_RS_MASK 0x00060000uL +#define CSR5_RS_SHIFT 17 + +/** 000 - Stopped; RESET or STOP RECEIVE command issued. */ +#define CSR5_RS_STOPPED 0u +/** 001 - Running, fetching the receive descriptor. */ +#define CSR5_RS_RUNNING_FD 1u +/** 010 - Running, waiting for the end-of-receive packet before prefetch of the + *next descriptor. */ +#define CSR5_RS_RUNNING_WR 2u +/** 011 - Running, waiting for the receive packet. */ +#define CSR5_RS_RUNNING_RB 3u +/** 100 - Suspended, unavailable receive buffer. */ +#define CSR5_RS_SUSPENDED 4u +/** 101 - Running, closing the receive descriptor. */ +#define CSR5_RS_RUNNING_CD 5u +/** 111 - Running, transferring data from FIFO to host memory. */ +#define CSR5_RS_RUNNING_TD 7u + +/*------------------------------------------------------------------------------ + * CSR5_NIS: + * NIS field of register CSR5. + *------------------------------------------------------------------------------ + * Normal interrupt summary + */ +#define CSR5_NIS_OFFSET 0x28 +#define CSR5_NIS_MASK 0x00010000uL +#define CSR5_NIS_SHIFT 16 + +/*------------------------------------------------------------------------------ + * CSR5_AIS: + * AIS field of register CSR5. + *------------------------------------------------------------------------------ + * Abnormal interrupt summary + */ +#define CSR5_AIS_OFFSET 0x28 +#define CSR5_AIS_MASK 0x00008000UL +#define CSR5_AIS_SHIFT 15 + +/*------------------------------------------------------------------------------ + * CSR5_ERI: + * ERI field of register CSR5. + *------------------------------------------------------------------------------ + * Early receive interrupt + */ +#define CSR5_ERI_OFFSET 0x28 +#define CSR5_ERI_MASK 0x00004000UL +#define CSR5_ERI_SHIFT 14 + +/*------------------------------------------------------------------------------ + * CSR5_GTE: + * GTE field of register CSR5. + *------------------------------------------------------------------------------ + * General-purpose timer expiration + */ +#define CSR5_GTE_OFFSET 0x28 +#define CSR5_GTE_MASK 0x00000800UL +#define CSR5_GTE_SHIFT 11 + +/*------------------------------------------------------------------------------ + * CSR5_ETI: + * ETI field of register CSR5. + *------------------------------------------------------------------------------ + * Early transmit interrupt + */ +#define CSR5_ETI_OFFSET 0x28 +#define CSR5_ETI_MASK 0x00000400UL +#define CSR5_ETI_SHIFT 10 + +/*------------------------------------------------------------------------------ + * CSR5_RPS: + * RPS field of register CSR5. + *------------------------------------------------------------------------------ + * Receive process stopped + */ +#define CSR5_RPS_OFFSET 0x28 +#define CSR5_RPS_MASK 0x00000100UL +#define CSR5_RPS_SHIFT 8 + +/*------------------------------------------------------------------------------ + * CSR5_RU: + * RU field of register CSR5. + *------------------------------------------------------------------------------ + * Receive buffer unavailable + */ +#define CSR5_RU_OFFSET 0x28 +#define CSR5_RU_MASK 0x00000080UL +#define CSR5_RU_SHIFT 7 + +/*------------------------------------------------------------------------------ + * CSR5_RI: + * RI field of register CSR5. + *------------------------------------------------------------------------------ + * Receive interrupt + */ +#define CSR5_RI_OFFSET 0x28 +#define CSR5_RI_MASK 0x00000040UL +#define CSR5_RI_SHIFT 6 + +/*------------------------------------------------------------------------------ + * CSR5_UNF: + * UNF field of register CSR5. + *------------------------------------------------------------------------------ + * Transmit underflow + */ +#define CSR5_UNF_OFFSET 0x28 +#define CSR5_UNF_MASK 0x00000020UL +#define CSR5_UNF_SHIFT 5 + +/*------------------------------------------------------------------------------ + * CSR5_TU: + * TU field of register CSR5. + *------------------------------------------------------------------------------ + * Transmit buffer unavailable + */ +#define CSR5_TU_OFFSET 0x28 +#define CSR5_TU_MASK 0x00000004UL +#define CSR5_TU_SHIFT 2 + +/*------------------------------------------------------------------------------ + * CSR5_TPS: + * TPS field of register CSR5. + *------------------------------------------------------------------------------ + * Transmit process stopped + */ +#define CSR5_TPS_OFFSET 0x28 +#define CSR5_TPS_MASK 0x00000002UL +#define CSR5_TPS_SHIFT 1 + +/*------------------------------------------------------------------------------ + * CSR5_TI: + * TI field of register CSR5. + *------------------------------------------------------------------------------ + * Transmit interrupt + */ +#define CSR5_TI_OFFSET 0x28 +#define CSR5_TI_MASK 0x00000001UL +#define CSR5_TI_SHIFT 0 + +/******************************************************************************* + * CSR6 register: + *------------------------------------------------------------------------------ + * CSR6 - Operation Mode Register + */ +#define CSR6_REG_OFFSET 0x30 + +/*------------------------------------------------------------------------------ + * CSR6_RA: + * RA field of register CSR6. + *------------------------------------------------------------------------------ + * Receive all + */ +#define CSR6_RA_OFFSET 0x30 +#define CSR6_RA_MASK 0x40000000UL +#define CSR6_RA_SHIFT 30 + +/*------------------------------------------------------------------------------ + * CSR6_TTM: + * TTM field of register CSR6. + *------------------------------------------------------------------------------ + * Transmit threshold mode + */ +#define CSR6_TTM_OFFSET 0x30 +#define CSR6_TTM_MASK 0x00400000UL +#define CSR6_TTM_SHIFT 22 + +/*------------------------------------------------------------------------------ + * CSR6_SF: + * SF field of register CSR6. + *------------------------------------------------------------------------------ + * Store and forward + */ +#define CSR6_SF_OFFSET 0x30 +#define CSR6_SF_MASK 0x00200000UL +#define CSR6_SF_SHIFT 21 + +/*------------------------------------------------------------------------------ + * CSR6_TR: + * TR field of register CSR6. + *------------------------------------------------------------------------------ + * Threshold control bits + */ +#define CSR6_TR_OFFSET 0x30 +#define CSR6_TR_MASK 0x0000C000UL +#define CSR6_TR_SHIFT 14 + +/*------------------------------------------------------------------------------ + * CSR6_ST: + * ST field of register CSR6. + *------------------------------------------------------------------------------ + * Start/stop transmit command + */ +#define CSR6_ST_OFFSET 0x30 +#define CSR6_ST_MASK 0x00002000UL +#define CSR6_ST_SHIFT 13 + +/*------------------------------------------------------------------------------ + * CSR6_FD: + * FD field of register CSR6. + *------------------------------------------------------------------------------ + * Full-duplex mode + */ +#define CSR6_FD_OFFSET 0x30 +#define CSR6_FD_MASK 0x00000200UL +#define CSR6_FD_SHIFT 9 + +/*------------------------------------------------------------------------------ + * CSR6_PM: + * PM field of register CSR6. + *------------------------------------------------------------------------------ + * Pass all multicast + */ +#define CSR6_PM_OFFSET 0x30 +#define CSR6_PM_MASK 0x00000080UL +#define CSR6_PM_SHIFT 7 + +/*------------------------------------------------------------------------------ + * CSR6_PR: + * PR field of register CSR6. + *------------------------------------------------------------------------------ + * Promiscuous mode + */ +#define CSR6_PR_OFFSET 0x30 +#define CSR6_PR_MASK 0x00000040UL +#define CSR6_PR_SHIFT 6 + +/*------------------------------------------------------------------------------ + * CSR6_IF: + * IF field of register CSR6. + *------------------------------------------------------------------------------ + * Inverse filtering + */ +#define CSR6_IF_OFFSET 0x30 +#define CSR6_IF_MASK 0x00000010UL +#define CSR6_IF_SHIFT 4 + +/*------------------------------------------------------------------------------ + * CSR6_PB: + * PB field of register CSR6. + *------------------------------------------------------------------------------ + * Pass bad frames + */ +#define CSR6_PB_OFFSET 0x30 +#define CSR6_PB_MASK 0x00000008UL +#define CSR6_PB_SHIFT 3 + +/*------------------------------------------------------------------------------ + * CSR6_HO: + * HO field of register CSR6. + *------------------------------------------------------------------------------ + * Hash-only filtering mode + */ +#define CSR6_HO_OFFSET 0x30 +#define CSR6_HO_MASK 0x00000004UL +#define CSR6_HO_SHIFT 2 + +/*------------------------------------------------------------------------------ + * CSR6_SR: + * SR field of register CSR6. + *------------------------------------------------------------------------------ + * Start/stop receive command + */ +#define CSR6_SR_OFFSET 0x30 +#define CSR6_SR_MASK 0x00000002UL +#define CSR6_SR_SHIFT 1 + +/*------------------------------------------------------------------------------ + * CSR6_HP: + * HP field of register CSR6. + *------------------------------------------------------------------------------ + * Hash/perfect receive filtering mode + */ +#define CSR6_HP_OFFSET 0x30 +#define CSR6_HP_MASK 0x00000001UL +#define CSR6_HP_SHIFT 0 + +/******************************************************************************* + * CSR7 register: + *------------------------------------------------------------------------------ + * CSR7 - Interrupt Enable Register + */ +#define CSR7_REG_OFFSET 0x38 + +/*------------------------------------------------------------------------------ + * CSR7_NIE: + * NIE field of register CSR7. + *------------------------------------------------------------------------------ + * Normal interrupt summary enable + */ +#define CSR7_NIE_OFFSET 0x38 +#define CSR7_NIE_MASK 0x00010000UL +#define CSR7_NIE_SHIFT 16 + +/*------------------------------------------------------------------------------ + * CSR7_AIE: + * AIE field of register CSR7. + *------------------------------------------------------------------------------ + * Abnormal interrupt summary enable + */ +#define CSR7_AIE_OFFSET 0x38 +#define CSR7_AIE_MASK 0x00008000UL +#define CSR7_AIE_SHIFT 15 + +/*------------------------------------------------------------------------------ + * CSR7_ERE: + * ERE field of register CSR7. + *------------------------------------------------------------------------------ + * Early receive interrupt enable + */ +#define CSR7_ERE_OFFSET 0x38 +#define CSR7_ERE_MASK 0x00004000UL +#define CSR7_ERE_SHIFT 14 + +/*------------------------------------------------------------------------------ + * CSR7_GTE: + * GTE field of register CSR7. + *------------------------------------------------------------------------------ + * General-purpose timer overflow enable + */ +#define CSR7_GTE_OFFSET 0x38 +#define CSR7_GTE_MASK 0x00000800UL +#define CSR7_GTE_SHIFT 11 + +/*------------------------------------------------------------------------------ + * CSR7_ETE: + * ETE field of register CSR7. + *------------------------------------------------------------------------------ + * Early transmit interrupt enable + */ +#define CSR7_ETE_OFFSET 0x38 +#define CSR7_ETE_MASK 0x00000400UL +#define CSR7_ETE_SHIFT 10 + +/*------------------------------------------------------------------------------ + * CSR7_RSE: + * RSE field of register CSR7. + *------------------------------------------------------------------------------ + * Receive stopped enable + */ +#define CSR7_RSE_OFFSET 0x38 +#define CSR7_RSE_MASK 0x00000100UL +#define CSR7_RSE_SHIFT 8 + +/*------------------------------------------------------------------------------ + * CSR7_RUE: + * RUE field of register CSR7. + *------------------------------------------------------------------------------ + * Receive buffer unavailable enable + */ +#define CSR7_RUE_OFFSET 0x38 +#define CSR7_RUE_MASK 0x00000080UL +#define CSR7_RUE_SHIFT 7 + +/*------------------------------------------------------------------------------ + * CSR7_RIE: + * RIE field of register CSR7. + *------------------------------------------------------------------------------ + * Receive interrupt enable + */ +#define CSR7_RIE_OFFSET 0x38 +#define CSR7_RIE_MASK 0x00000040UL +#define CSR7_RIE_SHIFT 6 + +/*------------------------------------------------------------------------------ + * CSR7_UNE: + * UNE field of register CSR7. + *------------------------------------------------------------------------------ + * Underflow interrupt enable + */ +#define CSR7_UNE_OFFSET 0x38 +#define CSR7_UNE_MASK 0x00000020UL +#define CSR7_UNE_SHIFT 5 + +/*------------------------------------------------------------------------------ + * CSR7_TUE: + * TUE field of register CSR7. + *------------------------------------------------------------------------------ + * Transmit buffer unavailable enable + */ +#define CSR7_TUE_OFFSET 0x38 +#define CSR7_TUE_MASK 0x00000004UL +#define CSR7_TUE_SHIFT 2 + +/*------------------------------------------------------------------------------ + * CSR7_TSE: + * TSE field of register CSR7. + *------------------------------------------------------------------------------ + * Transmit stopped enable + */ +#define CSR7_TSE_OFFSET 0x38 +#define CSR7_TSE_MASK 0x00000002UL +#define CSR7_TSE_SHIFT 1 + +/*------------------------------------------------------------------------------ + * CSR7_TIE: + * TIE field of register CSR7. + *------------------------------------------------------------------------------ + * Transmit interrupt enable + */ +#define CSR7_TIE_OFFSET 0x38 +#define CSR7_TIE_MASK 0x00000001UL +#define CSR7_TIE_SHIFT 0 + +/******************************************************************************* + * CSR8 register: + *------------------------------------------------------------------------------ + * CSR8 - Missed Frames and Overflow Counter Register + */ +#define CSR8_REG_OFFSET 0x40 + +/*------------------------------------------------------------------------------ + * CSR8_OCO: + * OCO field of register CSR8. + *------------------------------------------------------------------------------ + * Overflow counter overflow + */ +#define CSR8_OCO_OFFSET 0x40 +#define CSR8_OCO_MASK 0x10000000UL +#define CSR8_OCO_SHIFT 28 + +/*------------------------------------------------------------------------------ + * CSR8_FOC: + * FOC field of register CSR8. + *------------------------------------------------------------------------------ + * FIFO overflow counter + */ +#define CSR8_FOC_OFFSET 0x40 +#define CSR8_FOC_MASK 0x0FFE0000UL +#define CSR8_FOC_SHIFT 17 + +/*------------------------------------------------------------------------------ + * CSR8_MFO: + * MFO field of register CSR8. + *------------------------------------------------------------------------------ + * Missed frame overflow + */ +#define CSR8_MFO_OFFSET 0x40 +#define CSR8_MFO_MASK 0x00010000UL +#define CSR8_MFO_SHIFT 16 + +/*------------------------------------------------------------------------------ + * CSR8_MFC: + * MFC field of register CSR8. + *------------------------------------------------------------------------------ + * Missed frame counter + */ +#define CSR8_MFC_OFFSET 0x40 +#define CSR8_MFC_MASK 0x0000FFFFUL +#define CSR8_MFC_SHIFT 0 + +/******************************************************************************* + * CSR9 register: + *------------------------------------------------------------------------------ + * CSR9 - MII Management and Serial ROM Interface Register + */ +#define CSR9_REG_OFFSET 0x48 + +/*------------------------------------------------------------------------------ + * CSR9_MDI: + * MDI field of register CSR9. + *------------------------------------------------------------------------------ + * MII management data in signal + */ +#define CSR9_MDI_OFFSET 0x48 +#define CSR9_MDI_MASK 0x00080000UL +#define CSR9_MDI_SHIFT 19 + +/*------------------------------------------------------------------------------ + * CSR9_MII: + * MII field of register CSR9. + *------------------------------------------------------------------------------ + * MII management operation mode + */ +#define CSR9_MII_OFFSET 0x48 +#define CSR9_MII_MASK 0x00040000UL +#define CSR9_MII_SHIFT 18 + +/*------------------------------------------------------------------------------ + * CSR9_MDO: + * MDO field of register CSR9. + *------------------------------------------------------------------------------ + * MII management write data + */ +#define CSR9_MDO_OFFSET 0x48 +#define CSR9_MDO_MASK 0x00020000UL +#define CSR9_MDO_SHIFT 17 + +/*------------------------------------------------------------------------------ + * CSR9_MDC: + * MDC field of register CSR9. + *------------------------------------------------------------------------------ + * MII management clock + */ +#define CSR9_MDC_OFFSET 0x48 +#define CSR9_MDC_MASK 0x00010000UL +#define CSR9_MDC_SHIFT 16 + +/*------------------------------------------------------------------------------ + * CSR9_SDO: + * SDO field of register CSR9. + *------------------------------------------------------------------------------ + * Serial ROM data output + */ +#define CSR9_SDO_OFFSET 0x48 +#define CSR9_SDO_MASK 0x00000008UL +#define CSR9_SDO_SHIFT 3 + +/*------------------------------------------------------------------------------ + * CSR9_SDI: + * SDI field of register CSR9. + *------------------------------------------------------------------------------ + * Serial ROM data input + */ +#define CSR9_SDI_OFFSET 0x48 +#define CSR9_SDI_MASK 0x00000004UL +#define CSR9_SDI_SHIFT 2 + +/*------------------------------------------------------------------------------ + * CSR9_SCLK: + * SCLK field of register CSR9. + *------------------------------------------------------------------------------ + * Serial ROM clock + */ +#define CSR9_SCLK_OFFSET 0x48 +#define CSR9_SCLK_MASK 0x00000002UL +#define CSR9_SCLK_SHIFT 1 + +/*------------------------------------------------------------------------------ + * CSR9_SCS: + * SCS field of register CSR9. + *------------------------------------------------------------------------------ + * Serial ROM chip select + */ +#define CSR9_SCS_OFFSET 0x48 +#define CSR9_SCS_MASK 0x00000001UL +#define CSR9_SCS_SHIFT 0 + +/******************************************************************************* + * CSR11 register: + *------------------------------------------------------------------------------ + * CSR11 - General-Purpose Timer and Interrupt Mitigation Control Register + */ +#define CSR11_REG_OFFSET 0x58 + +/*------------------------------------------------------------------------------ + * CSR11_CS: + * CS field of register CSR11. + *------------------------------------------------------------------------------ + * Cycle size + */ +#define CSR11_CS_OFFSET 0x58 +#define CSR11_CS_MASK 0x80000000UL +#define CSR11_CS_SHIFT 31 + +/*------------------------------------------------------------------------------ + * CSR11_TT: + * TT field of register CSR11. + *------------------------------------------------------------------------------ + * Transmit timer + */ +#define CSR11_TT_OFFSET 0x58 +#define CSR11_TT_MASK 0x78000000UL +#define CSR11_TT_SHIFT 27 + +/*------------------------------------------------------------------------------ + * CSR11_NTP: + * NTP field of register CSR11. + *------------------------------------------------------------------------------ + * Number of transmit packets + */ +#define CSR11_NTP_OFFSET 0x58 +#define CSR11_NTP_MASK 0x07000000UL +#define CSR11_NTP_SHIFT 24 + +/*------------------------------------------------------------------------------ + * CSR11_RT: + * RT field of register CSR11. + *------------------------------------------------------------------------------ + * Receive timer + */ +#define CSR11_RT_OFFSET 0x58 +#define CSR11_RT_MASK 0x00F00000UL +#define CSR11_RT_SHIFT 20 + +/*------------------------------------------------------------------------------ + * CSR11_NRP: + * NRP field of register CSR11. + *------------------------------------------------------------------------------ + * Number of receive packets + */ +#define CSR11_NRP_OFFSET 0x58 +#define CSR11_NRP_MASK 0x000E0000UL +#define CSR11_NRP_SHIFT 17 + +/*------------------------------------------------------------------------------ + * CSR11_CON: + * CON field of register CSR11. + *------------------------------------------------------------------------------ + * Continuous mode + */ +#define CSR11_CON_OFFSET 0x58 +#define CSR11_CON_MASK 0x00010000UL +#define CSR11_CON_SHIFT 16 + +/*------------------------------------------------------------------------------ + * CSR11_TIM: + * TIM field of register CSR11. + *------------------------------------------------------------------------------ + * Timer value + */ +#define CSR11_TIM_OFFSET 0x58 +#define CSR11_TIM_MASK 0x0000FFFFUL +#define CSR11_TIM_SHIFT 0 + +#ifdef __cplusplus +} +#endif + +#endif /* MSS_ETHERNET_MAC_REGISTERS_H_*/ diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_user_cfg.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_user_cfg.h new file mode 100644 index 000000000..d4d2cc4df --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_user_cfg.h @@ -0,0 +1,26 @@ +/******************************************************************************* + * (c) Copyright 2007 Actel Corporation. All rights reserved. + * + * Actel:Firmware:MSS_Ethernet_MAC_Driver:2.0.103 configuration. + * + */ + + +#ifndef ACTEL__FIRMWARE__MSS_ETHERNET_MAC_DRIVER__2_0_103_CONFIGURATION_HEADER +#define ACTEL__FIRMWARE__MSS_ETHERNET_MAC_DRIVER__2_0_103_CONFIGURATION_HEADER + + +#define CORE_VENDOR "Actel" +#define CORE_LIBRARY "Firmware" +#define CORE_NAME "MSS_Ethernet_MAC_Driver" +#define CORE_VERSION "2.0.103" + +#define BUS_ARBITRATION_SCHEME 0 +#define PROGRAMMABLE_BURST_LENGTH 0 +#define RX_RING_SIZE 4 +#define SETUP_FRAME_TIME_OUT 10000 +#define STATE_CHANGE_TIME_OUT 10000 +#define TX_RING_SIZE 2 + +#endif // ACTEL__FIRMWARE__MSS_ETHERNET_MAC_DRIVER__2_0_103_CONFIGURATION_HEADER + diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/phy.c b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/phy.c new file mode 100644 index 000000000..e0433bace --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/phy.c @@ -0,0 +1,390 @@ +/***************************************************************************//** + * PHY access methods for DP83848C. + * The implementation in this file is specific to the DP83848C, + * If a different PHY support is required the PHY specific registers must + * be updated. + * (c) Copyright 2007 Actel Corporation + * + * SVN $Revision: 2324 $ + * SVN $Date: 2010-02-26 10:47:36 +0000 (Fri, 26 Feb 2010) $ + * + ******************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "mss_ethernet_mac.h" +#include "mss_ethernet_mac_regs.h" + +#include "phy.h" + +#include "FreeRTOS.h" +#include "task.h" + +extern MAC_instance_t g_mss_mac; + +/***************************** MDIO FUNCTIONS *********************************/ + +/* Defines ********************************************************************/ +#define MDIO_START 0x00004000UL +#define MDIO_READ 0x00002000UL +#define MDIO_WRITE 0x00001002UL +#define MDIO_ADDR_OFFSET 7UL +#define MDIO_ADDR_MASK 0x00000f80UL +#define MDIO_REG_ADDR_OFFSET 2UL +#define MDIO_REG_ADDR_MASK 0x0000007cUL +#define PREAMBLECOUNT 32UL +#define ONEMICROSECOND 20UL + +typedef enum { + MDIO_CMD_READ, + MDIO_CMD_WRITE +}mdio_cmd_t; + + + +/***************************************************************************//** + * Set clock high or low. + */ +static void +MDIO_management_clock +( + int32_t clock +) +{ + int32_t volatile a; + + MAC_BITBAND->CSR9_MDC = (uint32_t)clock; + + /* delay for 1us */ + for( a = 0; a < ONEMICROSECOND; a++ ){} +} + + +/***************************************************************************//** + * Send read or write command to PHY. + */ +static void +MDIO_send_cmd +( + uint8_t regad, + mdio_cmd_t mdio_cmd +) +{ + int32_t i; + uint16_t mask, data; + + /* enable MII output */ + MAC_BITBAND->CSR9_MDEN = 1; + + /* send 32 1's preamble */ + MAC_BITBAND->CSR9_MDO = 1; + for (i = 0; i < PREAMBLECOUNT; i++) { + MDIO_management_clock( 0 ); + MDIO_management_clock( 1 ); + } + + /* calculate data bits */ + data = MDIO_START | + (( mdio_cmd == MDIO_CMD_READ ) ? MDIO_READ : MDIO_WRITE ) | + ((g_mss_mac.phy_address << MDIO_ADDR_OFFSET) & MDIO_ADDR_MASK) | + ((regad << MDIO_REG_ADDR_OFFSET) & MDIO_REG_ADDR_MASK); + + /* sent out */ + for( mask = 0x00008000L; mask>0; mask >>= 1 ) + { + if ((mask == 0x2) && (mdio_cmd == MDIO_CMD_READ)) { + /* enable MII input */ + MAC_BITBAND->CSR9_MDEN = 0; + } + + MDIO_management_clock( 0 ); + + /* prepare MDO */ + MAC_BITBAND->CSR9_MDO = (uint32_t)((mask & data) != 0 ? 1UL : 0UL); + + MDIO_management_clock( 1 ); + } +} + + +/***************************************************************************//** + * Reads a PHY register. + */ +static uint16_t +MDIO_read +( + uint8_t regad +) +{ + uint16_t mask; + uint16_t data; + + MDIO_send_cmd( regad, MDIO_CMD_READ); + + /* read data */ + data = 0; + for( mask = 0x00008000L; mask>0; mask >>= 1 ) + { + MDIO_management_clock( 0 ); + + /* read MDI */ + if(MAC_BITBAND-> CSR9_MDI != 0){ + data |= mask; + } + + MDIO_management_clock( 1 ); + } + + MDIO_management_clock( 0 ); + + return data; +} + + +/***************************************************************************//** + * Writes to a PHY register. + */ +static void +MDIO_write +( + uint8_t regad, + uint16_t data +) +{ + uint16_t mask; + + MDIO_send_cmd(regad, MDIO_CMD_WRITE); + + /* write data */ + for( mask = 0x00008000L; mask>0; mask >>= 1 ) + { + MDIO_management_clock( 0 ); + + /* prepare MDO */ + MAC_BITBAND->CSR9_MDO = (uint32_t)((mask & data) != 0 ? 1UL : 0UL); + + MDIO_management_clock( 1 ); + } + + MDIO_management_clock( 0 ); +} + + +/****************************** PHY FUNCTIONS *********************************/ + +/* Defines ********************************************************************/ + +/* Base registers */ +#define PHYREG_MIIMCR 0x00 /**< MII Management Control Register */ +#define MIIMCR_RESET (1<<15) +#define MIIMCR_LOOPBACK (1<<14) +#define MIIMCR_SPEED_SELECT (1<<13) +#define MIIMCR_ENABLE_AUTONEGOTIATION (1<<12) +#define MIIMCR_RESTART_AUTONEGOTIATION (1<<9) +#define MIIMCR_DUPLEX_MODE (1<<8) +#define MIIMCR_COLLISION_TEST (1<<7) + +#define PHYREG_MIIMSR 0x01 /**< MII Management Status Register */ +#define MIIMSR_ANC (1<<5) /**< Auto-Negotiation Completed. */ +#define MIIMSR_LINK (1<<2) /**< Link is established. */ + +#define PHYREG_PHYID1R 0x02 /**< PHY Identifier 1 Register */ +#define PHYREG_PHYID2R 0x03 /**< PHY Identifier 2 Register */ + +#define PHYREG_ANAR 0x04 /**< Auto-Negotiation Advertisement Register */ +#define ANAR_100FD (1<<8) +#define ANAR_100HD (1<<7) +#define ANAR_10FD (1<<6) +#define ANAR_10HD (1<<5) + +#define PHYREG_ANLPAR 0x05 /**< Auto-Negotiation Link Partner Ability Register */ +#define PHYREG_ANER 0x06 /**< Auto-Negotiation Expansion Register */ +#define PHYREG_NPAR 0x07 /**< Next Page Advertisement Register */ +/* 0x08- 0x0F Reserved */ +#define PHYREG_MFR 0x10 /**< Miscellaneous Features Register */ +#define PHYREG_ICSR 0x11 /**< Interrupt Control/Status Register */ + +#define PHYREG_DR 0x12 /**< Diagnostic Register */ +#define DR_DPLX (1<<11) +#define DR_DATA_RATE (1<<10) + +#define PHYREG_PMLR 0x13 /**< Power Management & Loopback Register */ +/* 0x14 Reserved */ +#define PHYREG_MCR 0x15 /**< Mode Control Register */ +#define MCR_LED_SEL (1<<9) +/* 0x16 Reserved */ +#define PHYREG_DCR 0x17 /**< Disconnect Counter */ +#define PHYREG_RECR 0x18 /**< Receive Error Counter */ +/* 0x19-0x1F Reserved */ + +/***************************************************************************//** + * Probe used PHY. + * + * return PHY address. If PHY don't fount, returns 255. + */ +uint8_t PHY_probe( void ) +{ + uint8_t phy; + uint8_t phy_found; + uint16_t reg; + + phy_found = 0; + for (phy = MSS_PHY_ADDRESS_MIN; phy <= MSS_PHY_ADDRESS_MAX; phy++) { + g_mss_mac.phy_address = phy; + + reg = MDIO_read( PHYREG_PHYID1R ); + + if ((reg != 0x0000ffffUL) && (reg != 0x00000000UL)) { + phy_found = 1; + phy = MSS_PHY_ADDRESS_MAX + 1; + } + } + + if( phy_found == 0 ) { + g_mss_mac.phy_address = MSS_PHY_ADDRESS_AUTO_DETECT; + } + return g_mss_mac.phy_address; +} + + +/***************************************************************************//** + * Resets the PHY. + */ +void PHY_reset( void ) +{ + MDIO_write( PHYREG_MIIMCR, MIIMCR_RESET ); + MDIO_write( PHYREG_MIIMCR, + MIIMCR_ENABLE_AUTONEGOTIATION | + MIIMCR_RESTART_AUTONEGOTIATION | + MIIMCR_COLLISION_TEST ); +} + + +/***************************************************************************//** + * Restarts PHY auto-negotiation and wait until it's over. + */ +void PHY_auto_negotiate( void ) +{ + uint16_t reg; + + reg = MDIO_read( PHYREG_MIIMCR ); + MDIO_write( PHYREG_MIIMCR, + (uint16_t)( MIIMCR_ENABLE_AUTONEGOTIATION | + MIIMCR_RESTART_AUTONEGOTIATION | + reg) ); + + for( ;; ) { + reg = MDIO_read( PHYREG_MIIMSR ); + if( (reg & MIIMSR_ANC) != 0 ) { + break; + } else { + vTaskDelay( 200 ); + } + } +} + + +/***************************************************************************//** + * Returns link status. + * + * @return #MAC_LINK_STATUS_LINK if link is up. + */ +uint8_t PHY_link_status( void ) +{ + uint8_t retval = 0; + if(( MDIO_read( PHYREG_MIIMSR ) & MIIMSR_LINK ) != 0 ){ + retval = MSS_MAC_LINK_STATUS_LINK; + } + return retval; +} + + +/***************************************************************************//** + * Returns link type. + * + * @return the logical OR of the following values: + * #MAC_LINK_STATUS_100MB - Connection is 100Mb + * #MAC_LINK_STATUS_FDX - Connection is full duplex + */ +uint8_t PHY_link_type( void ) +{ + uint16_t diagnostic; + uint8_t type = 0; + + diagnostic = MDIO_read( PHYREG_DR ); + + if( (diagnostic & DR_DPLX) != 0 ) { + type = MSS_MAC_LINK_STATUS_FDX; + } + + if( (diagnostic & DR_DATA_RATE) != 0 ) { + type |= MSS_MAC_LINK_STATUS_100MB; + } + + return type; +} + + +/***************************************************************************//** + * Sets link type. + */ +void +PHY_set_link_type +( + uint8_t type +) +{ + uint16_t reg; + + reg = MDIO_read( PHYREG_ANAR ); + reg |= ANAR_100FD | ANAR_100HD | ANAR_10FD | ANAR_10HD; + + if( (type & MSS_MAC_LINK_STATUS_100MB) == 0 ) { + reg &= ~(ANAR_100FD | ANAR_100HD); + } + + if( (type & MSS_MAC_LINK_STATUS_FDX) == 0 ) { + reg &= ~(ANAR_100FD | ANAR_10FD); + } + + MDIO_write( PHYREG_ANAR, reg ); +} + + +/***************************************************************************//** + * Puts the Phy in Loopback mode + */ +uint16_t +PHY_set_loopback +( + uint8_t enable +) +{ + + uint16_t reg = 0; + + + reg = MDIO_read( PHYREG_MIIMCR ); + // If set to one we need to set the LOCAL Phy loopback + if(enable == 1) + reg |= MIIMCR_LOOPBACK; + else // else we want to clear the bit.. + reg ^= MIIMCR_LOOPBACK; + + + MDIO_write( PHYREG_MIIMCR,reg ); + reg = MDIO_read( PHYREG_MIIMCR ); + + return reg; + +} + +#ifdef __cplusplus +} +#endif + +/******************************** END OF FILE *********************************/ + diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/phy.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/phy.h new file mode 100644 index 000000000..e61daaed2 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/phy.h @@ -0,0 +1,78 @@ +/***************************************************************************//** + * PHY access methods. + * + * (c) Copyright 2007 Actel Corporation + * + * SVN $Revision: 2293 $ + * SVN $Date: 2010-02-24 13:52:02 +0000 (Wed, 24 Feb 2010) $ + * + ******************************************************************************/ + +#ifndef __MSS_ETHERNET_MAC_PHY_H +#define __MSS_ETHERNET_MAC_PHY_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************************************************************//** + * Resets the PHY. + */ +void PHY_reset( void ); + + +/***************************************************************************//** + * Restarts PHY auto-negotiation and wait until it's over. + */ +void PHY_auto_negotiate( void ); + + +/***************************************************************************//** + * Probe used PHY. + * + * return PHY address. If PHY don't fount, returns 255. + */ +uint8_t PHY_probe( void ); + + +/***************************************************************************//** + * Returns link status. + * + * @return #MAC_LINK_STATUS_LINK if link is up. + */ +uint8_t PHY_link_status( void ); + + +/***************************************************************************//** + * Returns link type. + * + * @return the logical OR of the following values: + * #MAC_LINK_STATUS_100MB - Connection is 100Mb + * #MAC_LINK_STATUS_FDX - Connection is full duplex + */ +uint8_t PHY_link_type( void ); + + +/***************************************************************************//** + * Sets link type. + */ +void +PHY_set_link_type +( + uint8_t type +); + +/***************************************************************************//** + * Sets/Clears the phy loop back mode, based on the enable value + */ +uint16_t +PHY_set_loopback +( + uint8_t enable +); + +#ifdef __cplusplus +} +#endif + +#endif /*__MSS_ETHERNET_MAC_PHY_H*/ diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_gpio/mss_gpio.c b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_gpio/mss_gpio.c new file mode 100644 index 000000000..e3be9aaa0 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_gpio/mss_gpio.c @@ -0,0 +1,283 @@ +/******************************************************************************* + * (c) Copyright 2008 Actel Corporation. All rights reserved. + * + * SmartFusion microcontroller subsystem GPIO bare metal driver implementation. + * + * SVN $Revision: 1753 $ + * SVN $Date: 2009-12-11 15:12:18 +0000 (Fri, 11 Dec 2009) $ + */ +#include "mss_gpio.h" +#include "../../CMSIS/mss_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*-------------------------------------------------------------------------*//** +* +*/ +#define GPIO_INT_ENABLE_MASK (uint32_t)0x00000008UL +#define OUTPUT_BUFFER_ENABLE_MASK 0x00000004UL + +#define NB_OF_GPIO (uint32_t)32 + +/*-------------------------------------------------------------------------*//** + * Lookup table of GPIO configuration registers address indexed on GPIO ID. + */ +static uint32_t volatile * const g_config_reg_lut[NB_OF_GPIO] = +{ + &(GPIO->GPIO_0_CFG), + &(GPIO->GPIO_1_CFG), + &(GPIO->GPIO_2_CFG), + &(GPIO->GPIO_3_CFG), + &(GPIO->GPIO_4_CFG), + &(GPIO->GPIO_5_CFG), + &(GPIO->GPIO_6_CFG), + &(GPIO->GPIO_7_CFG), + &(GPIO->GPIO_8_CFG), + &(GPIO->GPIO_9_CFG), + &(GPIO->GPIO_10_CFG), + &(GPIO->GPIO_11_CFG), + &(GPIO->GPIO_12_CFG), + &(GPIO->GPIO_13_CFG), + &(GPIO->GPIO_14_CFG), + &(GPIO->GPIO_15_CFG), + &(GPIO->GPIO_16_CFG), + &(GPIO->GPIO_17_CFG), + &(GPIO->GPIO_18_CFG), + &(GPIO->GPIO_19_CFG), + &(GPIO->GPIO_20_CFG), + &(GPIO->GPIO_21_CFG), + &(GPIO->GPIO_22_CFG), + &(GPIO->GPIO_23_CFG), + &(GPIO->GPIO_24_CFG), + &(GPIO->GPIO_25_CFG), + &(GPIO->GPIO_26_CFG), + &(GPIO->GPIO_27_CFG), + &(GPIO->GPIO_28_CFG), + &(GPIO->GPIO_29_CFG), + &(GPIO->GPIO_30_CFG), + &(GPIO->GPIO_31_CFG) +}; + +/*-------------------------------------------------------------------------*//** + * Lookup table of Cortex-M3 GPIO interrupt number indexed on GPIO ID. + */ +static const IRQn_Type g_gpio_irqn_lut[NB_OF_GPIO] = +{ + GPIO0_IRQn, + GPIO1_IRQn, + GPIO2_IRQn, + GPIO3_IRQn, + GPIO4_IRQn, + GPIO5_IRQn, + GPIO6_IRQn, + GPIO7_IRQn, + GPIO8_IRQn, + GPIO9_IRQn, + GPIO10_IRQn, + GPIO11_IRQn, + GPIO12_IRQn, + GPIO13_IRQn, + GPIO14_IRQn, + GPIO15_IRQn, + GPIO16_IRQn, + GPIO17_IRQn, + GPIO18_IRQn, + GPIO19_IRQn, + GPIO20_IRQn, + GPIO21_IRQn, + GPIO22_IRQn, + GPIO23_IRQn, + GPIO24_IRQn, + GPIO25_IRQn, + GPIO26_IRQn, + GPIO27_IRQn, + GPIO28_IRQn, + GPIO29_IRQn, + GPIO30_IRQn, + GPIO31_IRQn +}; + +/*-------------------------------------------------------------------------*//** + * MSS_GPIO_init + * See "mss_gpio.h" for details of how to use this function. + */ +void MSS_GPIO_init( void ) +{ + uint32_t i; + + /* reset MSS GPIO hardware */ + SYSREG->SOFT_RST_CR |= SYSREG_GPIO_SOFTRESET_MASK; + /* Clear any previously pended MSS GPIO interrupt */ + for ( i = 0U; i < NB_OF_GPIO; ++i ) + { + NVIC_ClearPendingIRQ( g_gpio_irqn_lut[i] ); + } + /* Take MSS GPIO hardware out of reset. */ + SYSREG->SOFT_RST_CR &= ~SYSREG_GPIO_SOFTRESET_MASK; +} + +/*-------------------------------------------------------------------------*//** + * MSS_GPIO_config + * See "mss_gpio.h" for details of how to use this function. + */ +void MSS_GPIO_config +( + mss_gpio_id_t port_id, + uint32_t config +) +{ + uint32_t gpio_idx = (uint32_t)port_id; + + ASSERT( gpio_idx < NB_OF_GPIO ); + + if ( gpio_idx < NB_OF_GPIO ) + { + *(g_config_reg_lut[gpio_idx]) = config; + } +} + +/*-------------------------------------------------------------------------*//** + * MSS_GPIO_set_output + * See "mss_gpio.h" for details of how to use this function. + */ +void MSS_GPIO_set_output +( + mss_gpio_id_t port_id, + uint8_t value +) +{ + uint32_t gpio_idx = (uint32_t)port_id; + + ASSERT( gpio_idx < NB_OF_GPIO ); + + if ( gpio_idx < NB_OF_GPIO ) + { + GPIO_BITBAND->GPIO_OUT[gpio_idx] = (uint32_t)value; + } +} + +/*-------------------------------------------------------------------------*//** + * MSS_GPIO_drive_inout + * See "mss_gpio.h" for details of how to use this function. + */ +void MSS_GPIO_drive_inout +( + mss_gpio_id_t port_id, + mss_gpio_inout_state_t inout_state +) +{ + uint32_t outputs_state; + uint32_t config; + uint32_t gpio_idx = (uint32_t)port_id; + + ASSERT( gpio_idx < NB_OF_GPIO ); + + if ( gpio_idx < NB_OF_GPIO ) + { + switch( inout_state ) + { + case MSS_GPIO_DRIVE_HIGH: + /* Set output high */ + outputs_state = GPIO->GPIO_OUT; + outputs_state |= (uint32_t)1 << gpio_idx; + GPIO->GPIO_OUT = outputs_state; + /* Enable output buffer */ + config = *(g_config_reg_lut[gpio_idx]); + config |= OUTPUT_BUFFER_ENABLE_MASK; + *(g_config_reg_lut[gpio_idx]) = config; + break; + + case MSS_GPIO_DRIVE_LOW: + /* Set output low */ + outputs_state = GPIO->GPIO_OUT; + outputs_state &= ~((uint32_t)((uint32_t)1 << gpio_idx)); + GPIO->GPIO_OUT = outputs_state; + /* Enable output buffer */ + config = *(g_config_reg_lut[gpio_idx]); + config |= OUTPUT_BUFFER_ENABLE_MASK; + *(g_config_reg_lut[gpio_idx]) = config; + break; + + case MSS_GPIO_HIGH_Z: + /* Disable output buffer */ + config = *(g_config_reg_lut[gpio_idx]); + config &= ~OUTPUT_BUFFER_ENABLE_MASK; + *(g_config_reg_lut[gpio_idx]) = config; + break; + + default: + ASSERT(0); + break; + } + } +} + +/*-------------------------------------------------------------------------*//** + * MSS_GPIO_enable_irq + * See "mss_gpio.h" for details of how to use this function. + */ +void MSS_GPIO_enable_irq +( + mss_gpio_id_t port_id +) +{ + uint32_t cfg_value; + uint32_t gpio_idx = (uint32_t)port_id; + + ASSERT( gpio_idx < NB_OF_GPIO ); + + if ( gpio_idx < NB_OF_GPIO ) + { + cfg_value = *(g_config_reg_lut[gpio_idx]); + *(g_config_reg_lut[gpio_idx]) = (cfg_value | GPIO_INT_ENABLE_MASK); + NVIC_EnableIRQ( g_gpio_irqn_lut[gpio_idx] ); + } +} + +/*-------------------------------------------------------------------------*//** + * MSS_GPIO_disable_irq + * See "mss_gpio.h" for details of how to use this function. + */ +void MSS_GPIO_disable_irq +( + mss_gpio_id_t port_id +) +{ + uint32_t cfg_value; + uint32_t gpio_idx = (uint32_t)port_id; + + ASSERT( gpio_idx < NB_OF_GPIO ); + + if ( gpio_idx < NB_OF_GPIO ) + { + cfg_value = *(g_config_reg_lut[gpio_idx]); + *(g_config_reg_lut[gpio_idx]) = (cfg_value & ~GPIO_INT_ENABLE_MASK); + } +} + +/*-------------------------------------------------------------------------*//** + * MSS_GPIO_clear_irq + * See "mss_gpio.h" for details of how to use this function. + */ +void MSS_GPIO_clear_irq +( + mss_gpio_id_t port_id +) +{ + uint32_t gpio_idx = (uint32_t)port_id; + + ASSERT( gpio_idx < NB_OF_GPIO ); + + if ( gpio_idx < NB_OF_GPIO ) + { + GPIO->GPIO_IRQ = ((uint32_t)1) << gpio_idx; + NVIC_ClearPendingIRQ( g_gpio_irqn_lut[gpio_idx] ); + } +} + +#ifdef __cplusplus +} +#endif + diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_gpio/mss_gpio.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_gpio/mss_gpio.h new file mode 100644 index 000000000..60220f128 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_gpio/mss_gpio.h @@ -0,0 +1,488 @@ +/******************************************************************************* + * (c) Copyright 2008 Actel Corporation. All rights reserved. + * + * SmartFusion Microcontroller Subsystem GPIO bare metal software driver public + * API. + * + * SVN $Revision: 1751 $ + * SVN $Date: 2009-12-11 15:05:48 +0000 (Fri, 11 Dec 2009) $ + */ + +/*=========================================================================*//** + @mainpage SmartFusion MSS GPIO Bare Metal Driver. + + @section intro_sec Introduction + The SmartFusion Microcontroller Subsystem (MSS) includes a block of 32 general + purpose input/outputs (GPIO). + This software driver provides a set of functions for controlling the MSS GPIO + block as part of a bare metal system where no operating system is available. + This driver can be adapted for use as part of an operating system but the + implementation of the adaptation layer between this driver and the operating + system's driver model is outside the scope of this driver. + + @section hw_dependencies Hardware Flow Dependencies + The configuration of all features of the MSS GPIOs is covered by this driver + with the exception of the SmartFusion IOMUX configuration. SmartFusion allows + multiple non-concurrent use of some external pins through IOMUX configuration. + This feature allows optimizing external pin usage by assigning external pins + for usage by either the microcontroller subsystem or the FPGA fabric. + The MSS GPIO ports 0 to 15 are always connected to external pins but GPIO ports + 16 to 31 are routed through IOMUX to the SmartFusion device external pins. + These IOMUX are configured using the MSS Configurator tool. + Make sure the MSS GPIOs 16 to 31 are enabled in the MSS Configurator tool if + you wish to use them + + @section theory_op Theory of Operation + The MSS GPIO driver uses the SmartFusion "Cortex Microcontroler Software + Interface Standard - Peripheral Access Layer" (CMSIS-PAL) to access MSS hardware + registers. You must ensure that the SmartFusion CMSIS-PAL is either included + in the software toolchain used to build your project or is included in your + project. The most up-to-date SmartFusion CMSIS-PAL files can be obtained using + the Actel Firmware Catalog. + + The MSS GPIO driver functions are grouped into the following categories: + - Initiliazation + - Configuration + - Reading and setting GPIO state + - Interrupt control + + The MSS GPIO driver is initialized through a call to the GPIO_init() function. + The GPIO_init() function must be called before any other GPIO driver functions + can be called. + + Each GPIO port is individually configured through a call to the + MSS_GPIO_config() function. Configuration includes deciding if a GPIO port + will be used as an input, an output or both. GPIO ports configured as inputs can be + further configured to generate interrupts based on the input's state. + Interrupts can be level or edge sensitive. + + The state of the GPIO ports can be read and set using the following functions: + - MSS_GPIO_get_inputs() + - MSS_GPIO_get_outputs() + - MSS_GPIO_set_outputs() + - MSS_GPIO_set_output() + - MSS_GPIO_drive_inout() + + Interrupts generated by GPIO ports configured as inputs are controlled using + the following functions: + - MSS_GPIO_enable_irq() + - MSS_GPIO_disable_irq() + - MSS_GPIO_clear_irq() + + *//*=========================================================================*/ +#ifndef MSS_GPIO_H_ +#define MSS_GPIO_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../../CMSIS/a2fxxxm3.h" + +/*-------------------------------------------------------------------------*//** + The mss_gpio_id_t enumeration is used to identify GPIOs as part of the + parameter to functions: + - MSS_GPIO_config(), + - MSS_GPIO_drive_inout(), + - MSS_GPIO_enable_irq(), + - MSS_GPIO_disable_irq(), + - MSS_GPIO_clear_irq() + */ +typedef enum __mss_gpio_id_t +{ + MSS_GPIO_0 = 0, + MSS_GPIO_1 = 1, + MSS_GPIO_2 = 2, + MSS_GPIO_3 = 3, + MSS_GPIO_4 = 4, + MSS_GPIO_5 = 5, + MSS_GPIO_6 = 6, + MSS_GPIO_7 = 7, + MSS_GPIO_8 = 8, + MSS_GPIO_9 = 9, + MSS_GPIO_10 = 10, + MSS_GPIO_11 = 11, + MSS_GPIO_12 = 12, + MSS_GPIO_13 = 13, + MSS_GPIO_14 = 14, + MSS_GPIO_15 = 15, + MSS_GPIO_16 = 16, + MSS_GPIO_17 = 17, + MSS_GPIO_18 = 18, + MSS_GPIO_19 = 19, + MSS_GPIO_20 = 20, + MSS_GPIO_21 = 21, + MSS_GPIO_22 = 22, + MSS_GPIO_23 = 23, + MSS_GPIO_24 = 24, + MSS_GPIO_25 = 25, + MSS_GPIO_26 = 26, + MSS_GPIO_27 = 27, + MSS_GPIO_28 = 28, + MSS_GPIO_29 = 29, + MSS_GPIO_30 = 30, + MSS_GPIO_31 = 31 +} mss_gpio_id_t; + +/*-------------------------------------------------------------------------*//** + GPIO ports definitions used to identify GPIOs as part of the parameter to + function MSS_GPIO_set_outputs(). + These definitions can also be used to identity GPIO through logical + operations on the return value of function MSS_GPIO_get_inputs(). + */ +#define MSS_GPIO_0_MASK 0x00000001UL +#define MSS_GPIO_1_MASK 0x00000002UL +#define MSS_GPIO_2_MASK 0x00000004UL +#define MSS_GPIO_3_MASK 0x00000008UL +#define MSS_GPIO_4_MASK 0x00000010UL +#define MSS_GPIO_5_MASK 0x00000020UL +#define MSS_GPIO_6_MASK 0x00000040UL +#define MSS_GPIO_7_MASK 0x00000080UL +#define MSS_GPIO_8_MASK 0x00000100UL +#define MSS_GPIO_9_MASK 0x00000200UL +#define MSS_GPIO_10_MASK 0x00000400UL +#define MSS_GPIO_11_MASK 0x00000800UL +#define MSS_GPIO_12_MASK 0x00001000UL +#define MSS_GPIO_13_MASK 0x00002000UL +#define MSS_GPIO_14_MASK 0x00004000UL +#define MSS_GPIO_15_MASK 0x00008000UL +#define MSS_GPIO_16_MASK 0x00010000UL +#define MSS_GPIO_17_MASK 0x00020000UL +#define MSS_GPIO_18_MASK 0x00040000UL +#define MSS_GPIO_19_MASK 0x00080000UL +#define MSS_GPIO_20_MASK 0x00100000UL +#define MSS_GPIO_21_MASK 0x00200000UL +#define MSS_GPIO_22_MASK 0x00400000UL +#define MSS_GPIO_23_MASK 0x00800000UL +#define MSS_GPIO_24_MASK 0x01000000UL +#define MSS_GPIO_25_MASK 0x02000000UL +#define MSS_GPIO_26_MASK 0x04000000UL +#define MSS_GPIO_27_MASK 0x08000000UL +#define MSS_GPIO_28_MASK 0x10000000UL +#define MSS_GPIO_29_MASK 0x20000000UL +#define MSS_GPIO_30_MASK 0x40000000UL +#define MSS_GPIO_31_MASK 0x80000000UL + +/*-------------------------------------------------------------------------*//** + * GPIO modes + */ +#define MSS_GPIO_INPUT_MODE 0x0000000002UL +#define MSS_GPIO_OUTPUT_MODE 0x0000000005UL +#define MSS_GPIO_INOUT_MODE 0x0000000003UL + +/*-------------------------------------------------------------------------*//** + * Possible GPIO inputs interrupt configurations. + */ +#define MSS_GPIO_IRQ_LEVEL_HIGH 0x0000000000UL +#define MSS_GPIO_IRQ_LEVEL_LOW 0x0000000020UL +#define MSS_GPIO_IRQ_EDGE_POSITIVE 0x0000000040UL +#define MSS_GPIO_IRQ_EDGE_NEGATIVE 0x0000000060UL +#define MSS_GPIO_IRQ_EDGE_BOTH 0x0000000080UL + +/*-------------------------------------------------------------------------*//** + * Possible states for GPIO configured as INOUT. + */ +typedef enum mss_gpio_inout_state +{ + MSS_GPIO_DRIVE_LOW = 0, + MSS_GPIO_DRIVE_HIGH, + MSS_GPIO_HIGH_Z +} mss_gpio_inout_state_t; + +/*-------------------------------------------------------------------------*//** + The MSS_GPIO_init() function initializes the SmartFusion MSS GPIO block. It + resets the MSS GPIO hardware block and it also clears any pending MSS GPIO + interrupts in the Cortex-M3 interrupt controller. + + @return + none. + */ +void MSS_GPIO_init( void ); + +/*-------------------------------------------------------------------------*//** + The MSS_GPIO_config() function is used to configure an individual + GPIO port. + + @param port_id + The port_id parameter identifies the GPIO port to be configured. + An enumeration item of the form MSS_GPIO_n where n is the number of the GPIO + port is used to identify the GPIO port. For example MSS_GPIO_0 identifies + the first GPIO port and MSS_GPIO_31 the last one. + + @param config + The config parameter specifies the configuration to be applied to the GPIO + port identified by the port_id parameter. It is a logical OR of the required + I/O mode and the required interrupt mode. The interrupt mode is not relevant + if the GPIO is configured as an output only. + These I/O mode constants are allowed: + - MSS_GPIO_INPUT_MODE + - MSS_GPIO_OUTPUT_MODE + - MSS_GPIO_INOUT_MODE + These interrupt mode constants are allowed: + - MSS_GPIO_IRQ_LEVEL_HIGH + - MSS_GPIO_IRQ_LEVEL_LOW + - MSS_GPIO_IRQ_EDGE_POSITIVE + - MSS_GPIO_IRQ_EDGE_NEGATIVE + - MSS_GPIO_IRQ_EDGE_BOTH + + @return + none. + + Example: + The following call will configure GPIO 4 as an input generating interrupts on + a low to high transition of the input: + @code + MSS_GPIO_config( MSS_GPIO_4, MSS_GPIO_INPUT_MODE | MSS_GPIO_IRQ_EDGE_POSITIVE ); + @endcode + */ +void MSS_GPIO_config +( + mss_gpio_id_t port_id, + uint32_t config +); + +/*-------------------------------------------------------------------------*//** + The MSS_GPIO_set_outputs() function is used to set the state of all GPIO + ports configured as outputs. + + @param value + The value parameter specifies the state of the GPIO ports configured as + outputs. It is a bit mask of the form (MSS_GPIO_n_MASK | MSS_GPIO_m_MASK) where n + and m are numbers identifying GPIOs. + For example (MSS_GPIO_0_MASK | MSS_GPIO_1_MASK | MSS_GPIO_2_MASK ) specifies + that the first, second and third GPIOs' must be set high and all other + outputs set low. + The driver provides 32 mask constants, MSS_GPIO_0_MASK to MSS_GPIO_31_MASK + inclusive, for this purpose. + + @return + none. + + Example 1: + Set GPIOs outputs 0 and 8 high and all other GPIO outputs low. + @code + MSS_GPIO_set_outputs( MSS_GPIO_0_MASK | MSS_GPIO_8_MASK ); + @endcode + + Example 2: + Set GPIOs outputs 2 and 4 low without affecting other GPIO outputs. + @code + uint32_t gpio_outputs; + gpio_outputs = MSS_GPIO_get_outputs(); + gpio_outputs &= ~( MSS_GPIO_2_MASK | MSS_GPIO_4_MASK ); + MSS_GPIO_set_outputs( gpio_outputs ); + @endcode + + @see MSS_GPIO_get_outputs() + */ +static __INLINE void +MSS_GPIO_set_outputs +( + uint32_t value +) +{ + GPIO->GPIO_OUT = value; +} + +/*-------------------------------------------------------------------------*//** + The MSS_GPIO_set_output() function is used to set the state of a single GPIO + port configured as output. + + @param port_id + The port_id parameter identifies the GPIO port that is to have its output set. + An enumeration item of the form MSS_GPIO_n where n is the number of the GPIO + port is used to identify the GPIO port. For example MSS_GPIO_0 identifies the + first GPIO port and MSS_GPIO_31 the last one. + + @param value + The value parameter specifies the desired state for the GPIO output. A value + of 0 will set the output low and a value of 1 will set the output high. + + @return + none. + */ +void MSS_GPIO_set_output +( + mss_gpio_id_t port_id, + uint8_t value +); + +/*-------------------------------------------------------------------------*//** + The MSS_GPIO_get_inputs() function is used to read the current state of all + GPIO ports confgured as inputs. + + @return + This function returns a 32 bit unsigned integer where each bit represents + the state of a GPIO input. The least significant bit represents the state of + GPIO input 0 and the most significant bit the state of GPIO input 31. + + Example: + Read and assign the current state of the GPIO outputs to a variable. + @code + uint32_t gpio_inputs; + gpio_inputs = MSS_GPIO_get_inputs(); + @endcode + */ +static __INLINE uint32_t +MSS_GPIO_get_inputs( void ) +{ + return GPIO->GPIO_IN; +} + +/*-------------------------------------------------------------------------*//** + The MSS_GPIO_get_outputs() function is used to read the current state of all + GPIO ports confgured as outputs. + + @return + This function returns a 32 bit unsigned integer where each bit represents + the state of a GPIO output. The least significant bit represents the state + of GPIO output 0 and the most significant bit the state of GPIO output 31. + + Example: + Read and assign the current state of the GPIO outputs to a variable. + @code + uint32_t gpio_outputs; + gpio_outputs = MSS_GPIO_get_outputs(); + @endcode + */ +static __INLINE uint32_t +MSS_GPIO_get_outputs( void ) +{ + return GPIO->GPIO_OUT; +} + +/*-------------------------------------------------------------------------*//** + The MSS_GPIO_drive_inout() function is used to set the output state of a single + GPIO port configured as an INOUT. An INOUT GPIO can be in one of three states: + - high + - low + - high impedance + An INOUT output would typically be used where several devices can drive the + state of a shared signal line. The high and low states are equivalent to the + high and low states of a GPIO configured as output. The high impedance state + is used to prevent the GPIO from driving its output state onto the signal line, + while at the same time allowing the input state of the GPIO to be read + + @param port_id + The port_id parameter identifies the GPIO port for which you want to change + the output state. + An enumeration item of the form MSS_GPIO_n where n is the number of the GPIO + port is used to identify the GPIO port. For example MSS_GPIO_0 identifies + the first GPIO port and MSS_GPIO_31 the last one. + + @param inout_state + The inout_state parameter specifies the state of the GPIO port identified by + the port_id parameter. Allowed values of type mss_gpio_inout_state_t are: + - MSS_GPIO_DRIVE_HIGH + - MSS_GPIO_DRIVE_LOW + - MSS_GPIO_HIGH_Z (high impedance) + + @return + none. + + Example: + The call to MSS_GPIO_drive_inout() below will set the GPIO 7 output to the + high impedance state. + @code + MSS_GPIO_drive_inout( MSS_GPIO_7, MSS_GPIO_HIGH_Z ); + @endcode + */ +void MSS_GPIO_drive_inout +( + mss_gpio_id_t port_id, + mss_gpio_inout_state_t inout_state +); + +/*-------------------------------------------------------------------------*//** + The MSS_GPIO_enable_irq() function is used to enable interrupt generation + for the specified GPIO input. Interrupts are generated based on the state of + the GPIO input and the interrupt mode configured for it by MSS_GPIO_config(). + + @param port_id + The port_id parameter identifies the GPIO port for which you want to enable + interrupt generation. + An enumeration item of the form MSS_GPIO_n where n is the number of the GPIO + port is used to identify the GPIO port. For example MSS_GPIO_0 identifies the + first GPIO port and MSS_GPIO_31 the last one. + + @return + none. + + Example: + The call to MSS_GPIO_enable_irq() below will allow GPIO 8 to generate + interrupts. + @code + MSS_GPIO_enable_irq( MSS_GPIO_8 ); + @endcode + */ +void MSS_GPIO_enable_irq +( + mss_gpio_id_t port_id +); + +/*-------------------------------------------------------------------------*//** + The MSS_GPIO_disable_irq() function is used to disable interrupt generation + for the specified GPIO input. + + @param port_id + The port_id parameter identifies the GPIO port for which you want to disable + interrupt generation. + An enumeration item of the form MSS_GPIO_n where n is the number of the GPIO + port is used to identify the GPIO port. For example MSS_GPIO_0 identifies the + first GPIO port and MSS_GPIO_31 the last one. + + @return + none. + + Example: + The call to MSS_GPIO_disable_irq() below will prevent GPIO 8 from generating + interrupts. + @code + MSS_GPIO_disable_irq( MSS_GPIO_8 ); + @endcode + */ +void MSS_GPIO_disable_irq +( + mss_gpio_id_t port_id +); + +/*-------------------------------------------------------------------------*//** + The MSS_GPIO_clear_irq() function is used to clear a pending interrupt from + the specified GPIO input. + Note: The MSS_GPIO_clear_irq() function must be called as part of any GPIO + interrupt service routine (ISR) in order to prevent the same interrupt event + retriggering a call to the GPIO ISR. The function also clears the interrupt + in the Cortex-M3 interrupt controller through a call to NVIC_ClearPendingIRQ(). + + @param port_id + The port_id parameter identifies the GPIO input for which you want to clear the + interrupt. + An enumeration item of the form MSS_GPIO_n where n is the number of the GPIO + port is used to identify the GPIO port. For example MSS_GPIO_0 identifies the + first GPIO port and MSS_GPIO_31 the last one. + + @return + none. + + Example: + The example below demonstrates the use of the MSS_GPIO_clear_irq() function + as part of the GPIO 9 interrupt service routine. + @code + void GPIO9_IRQHandler( void ) + { + do_interrupt_processing(); + + MSS_GPIO_clear_irq( MSS_GPIO_9 ); + } + @endcode + */ +void MSS_GPIO_clear_irq +( + mss_gpio_id_t port_id +); + +#ifdef __cplusplus +} +#endif + +#endif /* MSS_GPIO_H_ */ diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_pdma/mss_pdma.c b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_pdma/mss_pdma.c new file mode 100644 index 000000000..b49dca4ea --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_pdma/mss_pdma.c @@ -0,0 +1,413 @@ +/******************************************************************************* + * (c) Copyright 2008 Actel Corporation. All rights reserved. + * + * SmartFusion microcontroller subsystem Peripheral DMA bare metal software + * driver implementation. + * + * SVN $Revision: 2110 $ + * SVN $Date: 2010-02-05 15:24:19 +0000 (Fri, 05 Feb 2010) $ + */ +#include "mss_pdma.h" +#include "../../CMSIS/mss_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__GNUC__) +__attribute__((__interrupt__)) void DMA_IRQHandler( void ); +#else +void DMA_IRQHandler( void ); +#endif + +/***************************************************************************//** + Offset of the posted writes WRITE_ADJ bits in a PDMA channel's configuration + register. + */ +#define CHANNEL_N_POSTED_WRITE_ADJUST_SHIFT 14 + +/*-------------------------------------------------------------------------*//** + * Look-up table use to derice a channel's control register value from the + * requested source/destination. This table is incexed on the pdma_src_dest_t + * enumeration. + */ +#define CHANNEL_N_CTRL_PDMA_MASK (uint32_t)0x00000001 +#define CHANNEL_N_PERIPH_SELECT_SHIFT (uint32_t)23 +#define CHANNEL_N_DIRECTION_MASK (uint32_t)0x00000002 + +const uint32_t src_dest_to_ctrl_reg_lut[] = +{ + CHANNEL_N_CTRL_PDMA_MASK, /* PDMA_FROM_UART_0 */ + CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)1 << CHANNEL_N_PERIPH_SELECT_SHIFT) | CHANNEL_N_DIRECTION_MASK, /* PDMA_TO_UART_0 */ + CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)2 << CHANNEL_N_PERIPH_SELECT_SHIFT), /* PDMA_FROM_UART_1 */ + CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)3 << CHANNEL_N_PERIPH_SELECT_SHIFT) | CHANNEL_N_DIRECTION_MASK, /* PDMA_TO_UART_1 */ + CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)4 << CHANNEL_N_PERIPH_SELECT_SHIFT), /* PDMA_FROM_SPI_0 */ + CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)5 << CHANNEL_N_PERIPH_SELECT_SHIFT) | CHANNEL_N_DIRECTION_MASK, /* PDMA_TO_SPI_0 */ + CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)6 << CHANNEL_N_PERIPH_SELECT_SHIFT), /* PDMA_FROM_SPI_1 */ + CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)7 << CHANNEL_N_PERIPH_SELECT_SHIFT) | CHANNEL_N_DIRECTION_MASK, /* PDMA_TO_SPI_1 */ + CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)8 << CHANNEL_N_PERIPH_SELECT_SHIFT), /* PDMA_FROM_FPGA_1 */ + CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)8 << CHANNEL_N_PERIPH_SELECT_SHIFT) | CHANNEL_N_DIRECTION_MASK, /* PDMA_TO_FPGA_1 */ + CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)9 << CHANNEL_N_PERIPH_SELECT_SHIFT), /* PDMA_FROM_FPGA_0 */ + CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)9 << CHANNEL_N_PERIPH_SELECT_SHIFT) | CHANNEL_N_DIRECTION_MASK, /* PDMA_TO_FPGA_0 */ + CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)10 << CHANNEL_N_PERIPH_SELECT_SHIFT) | CHANNEL_N_DIRECTION_MASK, /* PDMA_TO_ACE */ + CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)11 << CHANNEL_N_PERIPH_SELECT_SHIFT) /* PDMA_FROM_ACE */ +}; + +/*-------------------------------------------------------------------------*//** + * + */ +#define PDMA_MASTER_ENABLE (uint32_t)0x04 +#define PDMA_SOFT_RESET (uint32_t)0x20 + +/*-------------------------------------------------------------------------*//** + * + */ +#define NB_OF_PDMA_CHANNELS 8 + +#define NEXT_CHANNEL_A 0U +#define NEXT_CHANNEL_B 1U + +#define CHANNEL_STOPPED 0U +#define CHANNEL_STARTED 1U + +static uint8_t g_pdma_next_channel[NB_OF_PDMA_CHANNELS]; +static uint8_t g_pdma_started_a[NB_OF_PDMA_CHANNELS]; +static uint8_t g_pdma_started_b[NB_OF_PDMA_CHANNELS]; +static pdma_channel_isr_t g_pdma_isr_table[NB_OF_PDMA_CHANNELS]; +static const uint16_t g_pdma_status_mask[NB_OF_PDMA_CHANNELS] = +{ + (uint16_t)0x0003, /* PDMA_CHANNEL_0 */ + (uint16_t)0x000C, /* PDMA_CHANNEL_1 */ + (uint16_t)0x0030, /* PDMA_CHANNEL_2 */ + (uint16_t)0x00C0, /* PDMA_CHANNEL_3 */ + (uint16_t)0x0300, /* PDMA_CHANNEL_4 */ + (uint16_t)0x0C00, /* PDMA_CHANNEL_5 */ + (uint16_t)0x3000, /* PDMA_CHANNEL_6 */ + (uint16_t)0xC000, /* PDMA_CHANNEL_7 */ +}; + + + +/***************************************************************************//** + * See mss_pdma.h for description of this function. + */ +void PDMA_init( void ) +{ + int32_t i; + + /* Enable PDMA master access to comms matrix. */ + SYSREG->AHB_MATRIX_CR |= PDMA_MASTER_ENABLE; + + /* Reset PDMA block. */ + SYSREG->SOFT_RST_CR |= PDMA_SOFT_RESET; + + /* Clear any previously pended MSS PDMA interrupt */ + NVIC_ClearPendingIRQ( DMA_IRQn ); + + /* Take PDMA controller out of reset*/ + SYSREG->SOFT_RST_CR &= ~PDMA_SOFT_RESET; + + /* Initialize channels state information. */ + for ( i = 0; i < NB_OF_PDMA_CHANNELS; ++i ) + { + g_pdma_next_channel[i] = NEXT_CHANNEL_A; + g_pdma_started_a[i] = CHANNEL_STOPPED; + g_pdma_started_b[i] = CHANNEL_STOPPED; + g_pdma_isr_table[i] = 0; + } +} + +/***************************************************************************//** + * See mss_pdma.h for description of this function. + */ +#define CHANNEL_RESET_MASK (uint32_t)0x00000020 + +void PDMA_configure +( + pdma_channel_id_t channel_id, + pdma_src_dest_t src_dest, + uint32_t channel_cfg, + uint8_t write_adjust +) +{ + /* Reset the channel. */ + PDMA->CHANNEL[channel_id].CRTL |= CHANNEL_RESET_MASK; + PDMA->CHANNEL[channel_id].CRTL &= ~CHANNEL_RESET_MASK; + + /* Configure PDMA channel's data source and destination. */ + if ( src_dest != PDMA_MEM_TO_MEM ) + { + PDMA->CHANNEL[channel_id].CRTL |= src_dest_to_ctrl_reg_lut[src_dest]; + } + + /* Configure PDMA channel trnasfer size, priority, source and destination address increment. */ + PDMA->CHANNEL[channel_id].CRTL |= channel_cfg; + + /* Posted write adjust. */ + PDMA->CHANNEL[channel_id].CRTL |= ((uint32_t)write_adjust << CHANNEL_N_POSTED_WRITE_ADJUST_SHIFT); +} + +/***************************************************************************//** + * See mss_pdma.h for description of this function. + */ +#define PAUSE_MASK (uint32_t)0x00000010 + +#define BUFFER_B_SELECT_MASK (uint32_t)0x00000004 + +#define CLEAR_PORT_A_DONE_MASK (uint32_t)0x00000080 +#define CLEAR_PORT_B_DONE_MASK (uint32_t)0x00000100 + +#define PORT_A_COMPLETE_MASK (uint32_t)0x00000001 +#define PORT_B_COMPLETE_MASK (uint32_t)0x00000002 + +void PDMA_start +( + pdma_channel_id_t channel_id, + uint32_t src_addr, + uint32_t dest_addr, + uint16_t transfer_count +) +{ + /* Pause transfer. */ + PDMA->CHANNEL[channel_id].CRTL |= PAUSE_MASK; + + /* Clear complete transfers. */ + if ( PDMA->CHANNEL[channel_id].STATUS & PORT_A_COMPLETE_MASK ) + { + PDMA->CHANNEL[channel_id].CRTL |= CLEAR_PORT_A_DONE_MASK; + g_pdma_started_a[channel_id] = CHANNEL_STOPPED; + } + if ( PDMA->CHANNEL[channel_id].STATUS & PORT_B_COMPLETE_MASK ) + { + PDMA->CHANNEL[channel_id].CRTL |= CLEAR_PORT_B_DONE_MASK; + g_pdma_started_b[channel_id] = CHANNEL_STOPPED; + } + + /* Load source, destination and transfer count. */ + if ( PDMA->CHANNEL[channel_id].STATUS & BUFFER_B_SELECT_MASK ) + { + g_pdma_next_channel[channel_id] = NEXT_CHANNEL_A; + g_pdma_started_b[channel_id] = CHANNEL_STARTED; + + PDMA->CHANNEL[channel_id].BUFFER_B_SRC_ADDR = src_addr; + PDMA->CHANNEL[channel_id].BUFFER_B_DEST_ADDR = dest_addr; + PDMA->CHANNEL[channel_id].BUFFER_B_TRANSFER_COUNT = transfer_count; + } + else + { + g_pdma_next_channel[channel_id] = NEXT_CHANNEL_B; + g_pdma_started_a[channel_id] = CHANNEL_STARTED; + + PDMA->CHANNEL[channel_id].BUFFER_A_SRC_ADDR = src_addr; + PDMA->CHANNEL[channel_id].BUFFER_A_DEST_ADDR = dest_addr; + PDMA->CHANNEL[channel_id].BUFFER_A_TRANSFER_COUNT = transfer_count; + } + + /* Start transfer */ + PDMA->CHANNEL[channel_id].CRTL &= ~PAUSE_MASK; +} + +/***************************************************************************//** + * See mss_pdma.h for description of this function. + */ +void PDMA_load_next_buffer +( + pdma_channel_id_t channel_id, + uint32_t src_addr, + uint32_t dest_addr, + uint16_t transfer_count +) +{ + if ( NEXT_CHANNEL_A == g_pdma_next_channel[channel_id] ) + { + /* Wait for channel A current transfer completion. */ + if ( CHANNEL_STARTED == g_pdma_started_a[channel_id] ) + { + uint32_t completed; + uint32_t channel_mask; + channel_mask = (uint32_t)1 << ((uint32_t)channel_id * 2U); + do { + completed = PDMA->BUFFER_STATUS & channel_mask; + } while( !completed ); + PDMA->CHANNEL[channel_id].CRTL |= CLEAR_PORT_A_DONE_MASK; + } + /* Load source, destination and transfer count. */ + PDMA->CHANNEL[channel_id].BUFFER_A_SRC_ADDR = src_addr; + PDMA->CHANNEL[channel_id].BUFFER_A_DEST_ADDR = dest_addr; + PDMA->CHANNEL[channel_id].BUFFER_A_TRANSFER_COUNT = transfer_count; + + /* Update channel state information. */ + g_pdma_next_channel[channel_id] = NEXT_CHANNEL_B; + g_pdma_started_a[channel_id] = CHANNEL_STARTED; + } + else + { + /* Wait for channel B current transfer completion. */ + if ( CHANNEL_STARTED == g_pdma_started_b[channel_id] ) + { + uint32_t completed; + uint32_t channel_mask; + channel_mask = (uint32_t)1 << (((uint32_t)channel_id * 2U) + 1U); + do { + completed = PDMA->BUFFER_STATUS & channel_mask; + } while( !completed ); + PDMA->CHANNEL[channel_id].CRTL |= CLEAR_PORT_B_DONE_MASK; + } + /* Load source, destination and transfer count. */ + PDMA->CHANNEL[channel_id].BUFFER_B_SRC_ADDR = src_addr; + PDMA->CHANNEL[channel_id].BUFFER_B_DEST_ADDR = dest_addr; + PDMA->CHANNEL[channel_id].BUFFER_B_TRANSFER_COUNT = transfer_count; + + /* Update channel state information. */ + g_pdma_next_channel[channel_id] = NEXT_CHANNEL_A; + g_pdma_started_b[channel_id] = CHANNEL_STARTED; + } +} + +/***************************************************************************//** + * See mss_pdma.h for description of this function. + */ +uint32_t PDMA_status +( + pdma_channel_id_t channel_id +) +{ + uint32_t status; + + status = PDMA->CHANNEL[channel_id].STATUS & (PORT_A_COMPLETE_MASK | PORT_B_COMPLETE_MASK); + + return status; +} + +/***************************************************************************//** + * + */ +#define CHANNEL_0_STATUS_BITS_MASK (uint16_t)0x0003 +#define CHANNEL_1_STATUS_BITS_MASK (uint16_t)0x000C +#define CHANNEL_2_STATUS_BITS_MASK (uint16_t)0x0030 +#define CHANNEL_3_STATUS_BITS_MASK (uint16_t)0x00C0 +#define CHANNEL_4_STATUS_BITS_MASK (uint16_t)0x0300 +#define CHANNEL_5_STATUS_BITS_MASK (uint16_t)0x0C00 +#define CHANNEL_6_STATUS_BITS_MASK (uint16_t)0x3000 +#define CHANNEL_7_STATUS_BITS_MASK (uint16_t)0xC000 + +static pdma_channel_id_t get_channel_id_from_status +( + uint16_t status +) +{ + pdma_channel_id_t channel_id = PDMA_CHANNEL_0; + + if ( status & CHANNEL_0_STATUS_BITS_MASK ) + { + channel_id = PDMA_CHANNEL_0; + } + else if ( status & CHANNEL_1_STATUS_BITS_MASK ) + { + channel_id = PDMA_CHANNEL_1; + } + else if ( status & CHANNEL_2_STATUS_BITS_MASK ) + { + channel_id = PDMA_CHANNEL_2; + } + else if ( status & CHANNEL_3_STATUS_BITS_MASK ) + { + channel_id = PDMA_CHANNEL_3; + } + else if ( status & CHANNEL_4_STATUS_BITS_MASK ) + { + channel_id = PDMA_CHANNEL_4; + } + else if ( status & CHANNEL_5_STATUS_BITS_MASK ) + { + channel_id = PDMA_CHANNEL_5; + } + else if ( status & CHANNEL_6_STATUS_BITS_MASK ) + { + channel_id = PDMA_CHANNEL_6; + } + else if ( status & CHANNEL_7_STATUS_BITS_MASK ) + { + channel_id = PDMA_CHANNEL_7; + } + else + { + ASSERT(0); + } + return channel_id; +} + +/***************************************************************************//** + * + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void DMA_IRQHandler( void ) +#else +void DMA_IRQHandler( void ) +#endif +{ + uint16_t status; + pdma_channel_id_t channel_id; + + status = (uint16_t)PDMA->BUFFER_STATUS; + + do { + channel_id = get_channel_id_from_status( status ); + status &= (uint16_t)~g_pdma_status_mask[channel_id]; + if ( 0 != g_pdma_isr_table[channel_id]) + { + g_pdma_isr_table[channel_id](); + } + } while ( 0U != status ); + + NVIC_ClearPendingIRQ( DMA_IRQn ); +} + +/***************************************************************************//** + * See mss_pdma.h for description of this function. + */ +void PDMA_set_irq_handler +( + pdma_channel_id_t channel_id, + pdma_channel_isr_t handler +) +{ + /* Save address of handler function in PDMA driver ISR lookup table. */ + g_pdma_isr_table[channel_id] = handler; + + /* Enable PDMA channel's interrupt. */ + PDMA->CHANNEL[channel_id].CRTL |= PDMA_IRQ_ENABLE_MASK; + + /* Enable PDMA interrupt in Cortex-M3 NVIC. */ + NVIC_EnableIRQ( DMA_IRQn ); +} + +/***************************************************************************//** + * See mss_pdma.h for description of this function. + */ +void PDMA_enable_irq( pdma_channel_id_t channel_id ) +{ + PDMA->CHANNEL[channel_id].CRTL |= PDMA_IRQ_ENABLE_MASK; + NVIC_EnableIRQ( DMA_IRQn ); +} + +/***************************************************************************//** + * See mss_pdma.h for description of this function. + */ +void PDMA_clear_irq +( + pdma_channel_id_t channel_id +) +{ + /* Clear interrupt in PDMA controller. */ + PDMA->CHANNEL[channel_id].CRTL |= CLEAR_PORT_A_DONE_MASK; + PDMA->CHANNEL[channel_id].CRTL |= CLEAR_PORT_B_DONE_MASK; + + /* Clear interrupt in Cortex-M3 NVIC. */ + NVIC_ClearPendingIRQ( DMA_IRQn ); +} + +#ifdef __cplusplus +} +#endif + diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_pdma/mss_pdma.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_pdma/mss_pdma.h new file mode 100644 index 000000000..6f79226c3 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_pdma/mss_pdma.h @@ -0,0 +1,703 @@ +/******************************************************************************* + * (c) Copyright 2008 Actel Corporation. All rights reserved. + * + * SmartFusion microcontroller subsystem Peripheral DMA bare metal software + * driver public API. + * + * SVN $Revision: 2110 $ + * SVN $Date: 2010-02-05 15:24:19 +0000 (Fri, 05 Feb 2010) $ + */ +/*=========================================================================*//** + @mainpage SmartFusion MSS GPIO Bare Metal Driver. + + @section intro_sec Introduction + The SmartFusion Microcontroller Subsystem (MSS) includes an 8 channel + Peripheral DMA (PDMA) controller. + This software driver provides a set of functions for controlling the MSS PDMA + controller as part of a bare metal system where no operating system is available. + This driver can be adapted for use as part of an operating system but the + implementation of the adaptation layer between this driver and the operating + system's driver model is outside the scope of this driver. + + @section theory_op Theory of Operation + The MSS PDMA driver uses the SmartFusion "Cortex Microcontroler Software + Interface Standard - Peripheral Access Layer" (CMSIS-PAL) to access MSS hardware + registers. You must ensure that the SmartFusion CMSIS-PAL is either included + in the software toolchain used to build your project or is included in your + project. The most up-to-date SmartFusion CMSIS-PAL files can be obtained using + the Actel Firmware Catalog. + + The MSS PDMA driver functions are grouped into the following categories: + - Initialization + - Configuration + - DMA transfer control + - Interrupt control + + The MSS PDMA driver is initialized through a call to the PDMA_init() function. + The PDMA_init() function must be called before any other PDMA driver functions + can be called. + + Each PDMA channel is individually configured through a call to the PDMA_configure() + function. Configuration includes: + - channel priority + - transfer size + - source and/or destination address increment + - source or destination of the DMA transfer + PDMA channels can be divided into high and low priority channels. High priority + channels are given more opportunities to perform transfers than low priority + channels when there are continuous high priority channels requests. The ratio + of high priority to low priority PDMA transfers is configurable through the + PDMA_set_priority() function. + PDMA channels can be configured to perform byte (8 bits), half-word (16 bits) + or word (32 bits) transfers. + The source and destination address of a PDMA channel’s transfers can be + independently configured to increment by 0, 1, 2 or 4 bytes. For example, the + content of a byte buffer located in RAM can be transferred into a peripheral’s + transmit register by configuring the source address increment to one byte and + no increment of the destination address. + The source or destination of a PDMA channel’s transfers can be configured to + be one of the MSS peripherals. This allows the PDMA controller to use some + hardware flow control signaling with the peripheral to avoid overrunning the + peripheral’s data buffer when the peripheral is the destination of the DMA + transfer, or attempting to read data from the peripheral while it is not ready + when the peripheral is the source of the transfer. + A PDMA channel can also be configured to transfer data between two memory + mapped locations (memory to memory). No hardware flow control is used by the + PDMA controller for data transfer in this configuration. + + A DMA transfer can be initiated by a call to the PDMA_start() function after a + PDMA channel has been configured. Once started, further data can be pushed + through the PDMA channel by calling the PDMA_load_next_buffer() function. The + PDMA_load_next_buffer() function can be called every time a call to the + PDMA_status() function indicates that the PDMA channel used for the transfer + has a free buffer or it can be called as a result of a PDMA interrupt. + + A DMA transfer can be paused and resumed through calls to functions PDMA_pause() + and PDMA_resume(). + + Your application can manage DMA transfers using interrupts through the use of + the following functions: + - PDMA_set_irq_handler() + - PDMA_enable_irq() + - PDMA_clear_irq() + - PDMA_disable_irq() + The PDMA_set_irq_handler() function is used to register PDMA channel interrupt + handler functions with the driver. You must create and register an interrupt + handler function for each interrupt driven PDMA channel used by the application. + Use the PDMA_enable_irq() function to enable interrupts for the PDMA channels. + Every time a PDMA channel completes the transfer of a buffer it causes a PDMA + interrupt to occur and the PDMA driver will call the interrupt handler + registered by the application for that PDMA channel. + + *//*=========================================================================*/ +#ifndef __MSS_PERIPHERAL_DMA_H_ +#define __MSS_PERIPHERAL_DMA_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../../CMSIS/a2fxxxm3.h" + +/***************************************************************************//** + The pdma_channel_id_t enumeration is used to identify peripheral DMA channels. + It is used as function parameter to specify the PDMA channel used. + */ +typedef enum __pdma_channel_id +{ + PDMA_CHANNEL_0 = 0, + PDMA_CHANNEL_1, + PDMA_CHANNEL_2, + PDMA_CHANNEL_3, + PDMA_CHANNEL_4, + PDMA_CHANNEL_5, + PDMA_CHANNEL_6, + PDMA_CHANNEL_7 +} pdma_channel_id_t; + +/***************************************************************************//** + The pdma_src_dest_t enumeration is used to specify the source or destination + of transfers on a PDMA channel. It specifies which hardware peripheral will be + the source or destination of DMA transfers. This allows the PDMA controller + to use hardware flow control signals to avoid overrunning a + destination peripheral with data it is not ready to receive, or attempting to + transfer data from a peripheral while it has no data ready to transfer. + The pdma_src_dest_t enumeration can also be used to specify that a PDMA channel + is configured to transfer data between two memory mapped locations + (memory to memory). No hardware data flow control is used by the PDMA + controller in this configuration. + This enumeration is used as parameter to function PDMA_configure(). + */ +typedef enum __pdma_src_dest +{ + PDMA_FROM_UART_0 = 0, + PDMA_TO_UART_0, + PDMA_FROM_UART_1, + PDMA_TO_UART_1, + PDMA_FROM_SPI_0, + PDMA_TO_SPI_0, + PDMA_FROM_SPI_1, + PDMA_TO_SPI_1, + PDMA_FROM_FPGA_1, + PDMA_TO_FPGA_1, + PDMA_FROM_FPGA_0, + PDMA_TO_FPGA_0, + PDMA_TO_ACE, + PDMA_FROM_ACE, + PDMA_MEM_TO_MEM +} pdma_src_dest_t; + +/***************************************************************************//** + The pdma_priority_ratio_t enumeration is used to configure the ratio of high + priority to low priority PDMA channels. This ratio specifies how many DMA + transfer opportunities will be given to high priority channels before a DMA + transfer opportunity is given to a low priority channel when there are + continuous requests from high priority channels. This enumeration is used as + parameter to function PDMA_set_priority_ratio(). + */ +typedef enum __pdma_priority_ratio_t +{ + PDMA_ROUND_ROBIN = 0, + PDMA_RATIO_HIGH_LOW_1_TO_1 = 1, + PDMA_RATIO_HIGH_LOW_3_TO_1 = 3, + PDMA_RATIO_HIGH_LOW_7_TO_1 = 7, + PDMA_RATIO_HIGH_LOW_15_TO_1 = 15, + PDMA_RATIO_HIGH_LOW_31_TO_1 = 31, + PDMA_RATIO_HIGH_LOW_63_TO_1 = 63, + PDMA_RATIO_HIGH_LOW_127_TO_1 = 127, + PDMA_RATIO_HIGH_LOW_255_TO_1 = 255 +} pdma_priority_ratio_t; + + +/***************************************************************************//** + The pdma_channel_isr_t type is a pointer to a PDMA channel interrupt handler + function. It specifies the function prototype of functions that can be + registered as PDMA channel interrupt handlers. It is used as parameter to + function PDMA_set_irq_handler(). + */ +typedef void (*pdma_channel_isr_t)( void ); +/***************************************************************************//** + These constants are used to build the channel_cfg parameter of the + PDMA_configure() function. They specify whether a channel is a high or low + priority channel. + */ +#define PDMA_LOW_PRIORITY 0x0000 +#define PDMA_HIGH_PRIORITY 0x0200 + +/***************************************************************************//** + These constants are used to build the channel_cfg parameter of the + PDMA_configure() function. They specify the data width of the transfers + performed by a PDMA channel. + */ +#define PDMA_BYTE_TRANSFER 0x0000 /* Byte transfers (8 bits) */ +#define PDMA_HALFWORD_TRANSFER 0x0004 /* Half-word transfers (16 bits) */ +#define PDMA_WORD_TRANSFER 0x0008 /* Word transfers (32 bits) */ + +/***************************************************************************//** + These constants are used to build the channel_cfg parameter of the + PDMA_configure() function. They specify the PDMA channel’s source and + destination address increment. + */ +#define PDMA_NO_INC 0 +#define PDMA_INC_SRC_ONE_BYTE 0x0400 +#define PDMA_INC_SRC_TWO_BYTES 0x0800 +#define PDMA_INC_SRC_FOUR_BYTES 0x0C00 +#define PDMA_INC_DEST_ONE_BYTE 0x1000 +#define PDMA_INC_DEST_TWO_BYTES 0x2000 +#define PDMA_INC_DEST_FOUR_BYTES 0x3000 + +/***************************************************************************//** + * Mask for various control register bits. + */ +#define PDMA_IRQ_ENABLE_MASK (uint32_t)0x00000040 +#define PDMA_PAUSE_MASK (uint32_t)0x00000010 + +/***************************************************************************//** + These constants are used to specify the src_addr parameter to the PDMA_start() + and PDMA_load_next_buffer() functions. They specify the receive register + address of peripherals that can be the source of a DMA transfer. + When a PDMA channel is configured for DMA transfers from a peripheral to memory, + the constant specifying that peripheral’s receive register address must be used + as the src_addr parameter. + */ +#define PDMA_SPI0_RX_REGISTER 0x40001010uL +#define PDMA_SPI1_RX_REGISTER 0x40011010uL +#define PDMA_UART0_RX_REGISTER 0x40000000uL +#define PDMA_UART1_RX_REGISTER 0x40010000uL +#define PDMA_ACE_PPE_DATAOUT 0x40021308uL + +/***************************************************************************//** + These constants are used to specify the dest_addr parameter to the PDMA_start() + and PDMA_load_next_buffer() functions. They specify the transmit register + address of peripherals that can be the destination of a DMA transfer. + When a PDMA channel is configured for DMA transfers from memory to a peripheral, + the constant specifying that peripheral’s transmit register address must be used + as the dest_addr parameter. + */ +#define PDMA_SPI0_TX_REGISTER 0x40001014uL +#define PDMA_SPI1_TX_REGISTER 0x40011014uL +#define PDMA_UART0_TX_REGISTER 0x40000000uL +#define PDMA_UART1_TX_REGISTER 0x40010000uL +#define PDMA_ACE_SSE_DATAIN 0x40020700uL + +/***************************************************************************//** + The PDMA_DEFAULT_WRITE_ADJ constant provides a suitable default value for the + PDMA_configure() function write_adjust parameter. + */ +#define PDMA_DEFAULT_WRITE_ADJ 10u + +/***************************************************************************//** + The PDMA_init() function initializes the peripheral DMA hardware and driver + internal data. It resets the PDMA and it also clears any pending PDMA + interrupts in the Cortex-M3 interrupt controller. When the function exits, it + takes the PDMA block out of reset. + */ +void PDMA_init( void ); + +/***************************************************************************//** + The PDMA_configure() function configures a PDMA channel. + It specifies: + - The peripheral which will be the source or destination of the DMA transfer. + - Whether the DMA channel will be a high or low priority channel + - The source and destination address increment that will take place after + each transfer. + + @param channel_id + The channel_id parameter identifies the PDMA channel used by the function. + + @param src_dest + The src_dest parameter specifies the source or destination of the DMA + transfers that will be performed. It can be one of the following: + - PDMA_FROM_UART_0 + - PDMA_TO_UART_0 + - PDMA_FROM_UART_1 + - PDMA_TO_UART_1 + - PDMA_FROM_SPI_0 + - PDMA_TO_SPI_0 + - PDMA_FROM_SPI_1 + - PDMA_TO_SPI_1 + - PDMA_FROM_FPGA_1 + - PDMA_TO_FPGA_1 + - PDMA_FROM_FPGA_0 + - PDMA_TO_FPGA_0 + - PDMA_TO_ACE + - PDMA_FROM_ACE + - PDMA_MEM_TO_MEM + + @param channel_cfg + The channel_cfg parameter specifies the configuration of the PDMA channel. + The configuration includes: + - channel priority + - transfer size + - source and/or destination address increment + The channel_cfg parameter value is a logical OR of: + One of the following to specify the channel priority: + - PDMA_LOW_PRIORITY + - PDMA_HIGH_PRIORITY + One of the following to specify the transfer size: + - PDMA_BYTE_TRANSFER + - PDMA_HALFWORD_TRANSFER + - PDMA_WORD_TRANSFER + One or two of the following to specify the source and/or destination address + increment: + - PDMA_NO_INC + - PDMA_INC_SRC_ONE_BYTE + - PDMA_INC_SRC_TWO_BYTES + - PDMA_INC_SRC_FOUR_BYTES + - PDMA_INC_DEST_ONE_BYTE + - PDMA_INC_DEST_TWO_BYTES + - PDMA_INC_DEST_FOUR_BYTES + + @param write_adjust + The write_adjust parameter specifies the number of Cortex-M3 clock cycles + the PDMA controller will wait before attempting another transfer cycle. This + delay is necessary when peripherals are used as destination of a DMA transfer + to ensure the DMA controller interprets the state of the peripheral’s ready + signal only after data has actually been written to the peripheral. This delay + accounts for posted writes (dump and run) for write accesses to peripherals. + The effect of posted writes is that if the PDMA performs a write operation to + a peripheral, the data is not actually written into the peripheral until + sometime after the PDMA controller thinks it is written. + A suitable value for write_adjust depends on the target of the DMA transfer. + Guidelines for choosing this value are as follows: + • The PDMA_DEFAULT_WRITE_ADJ constant provides a suitable default value + for the write_adjust parameter when the PDMA channel is configured for + transfers with MSS peripherals. + • The PDMA_DEFAULT_WRITE_ADJ constant can also be used for DMA transfers + with FPGA fabric implemented peripherals making use of the DMAREADY0 or + DMAREADY1fabric interface signal to indicate that the peripheral is + ready for another DMA transfer. + • The write_adjust parameter can be set to zero to achieve maximum transfer + speed for genuine memory to memory transfers. + • The internal latency of FPGA implemented peripherals will decide the + write_adjust value for fabric peripherals that do not use the DMAREADY0 + or DMAREADY1 fabric interface signals. You need to check the fabric + peripheral documentation for the value to use. + + Example: + @code + PDMA_configure + ( + PDMA_CHANNEL_0, + PDMA_TO_SPI_1, + PDMA_LOW_PRIORITY | PDMA_BYTE_TRANSFER | PDMA_INC_SRC_ONE_BYTE, + PDMA_DEFAULT_WRITE_ADJ + ); + @endcode + */ +void PDMA_configure +( + pdma_channel_id_t channel_id, + pdma_src_dest_t src_dest, + uint32_t channel_cfg, + uint8_t write_adjust +); + + +/***************************************************************************//** + The PDMA_set_priority_ratio() function sets the ratio of high priority to low + priority DMA access opportunities. This ratio is used by the PDMA controller + arbiter to decide which PDMA channel will be given the opportunity to perform + a transfer when multiple PDMA channels are requesting to transfer data at the + same time. The priority ratio specifies how many DMA transfer opportunities + will be given to high priority channels before a DMA transfer opportunity is + given to a low priority channel when there are continuous requests from high + priority channels. + + @param priority_ratio + The priority_ratio parameter specifies the ratio of DMA access opportunities + given to high priority channels versus low priority channels. + Allowed values for this parameter are: + - PDMA_ROUND_ROBIN + - PDMA_RATIO_HIGH_LOW_1_TO_1 + - PDMA_RATIO_HIGH_LOW_3_TO_1 + - PDMA_RATIO_HIGH_LOW_7_TO_1 + - PDMA_RATIO_HIGH_LOW_15_TO_1 + - PDMA_RATIO_HIGH_LOW_31_TO_1 + - PDMA_RATIO_HIGH_LOW_63_TO_1 + - PDMA_RATIO_HIGH_LOW_127_TO_1 + - PDMA_RATIO_HIGH_LOW_255_TO_1 + + Example: + @code + PDMA_set_priority_ratio( PDMA_ROUND_ROBIN ); + @endcode + */ +static __INLINE void PDMA_set_priority_ratio +( + pdma_priority_ratio_t priority_ratio +) +{ + PDMA->RATIO_HIGH_LOW = (uint32_t)priority_ratio; +} + +/***************************************************************************//** + The PDMA_start() function initiates a DMA transfer. It specifies the source + and destination address of the transfer as well as the number of transfers + that must take place. The source and destination addresses can be the address + of peripheral registers. + + @param channel_id + The channel_id parameter identifies the PDMA channel used by the function. + + @param src_addr + The src_addr parameter specifies the address location of the data to be + transferred. You must ensure that this source address is consistent with the + DMA source configured for the selected channel using the PDMA_configure() + function. + For DMA transfers from MSS peripheral to memory, the following src_addr + parameter values are allowed: + • PDMA_SPI0_RX_REGISTER + • PDMA_SPI1_RX_REGISTER + • PDMA_UART0_RX_REGISTER + • PDMA_UART1_RX_REGISTER + • PDMA_ACE_PPE_DATAOUT + For DMA transfers from FPGA fabric peripheral to memory, the following + src_addr parameter values are allowed: + • An address in the FPGA fabric address space (0x40050000-0x400FFFFF) + For DMA transfers from memory to MSS peripheral, or from memory to FPGA + fabric peripheral, or from memory to memory, the following src_addr + parameter values are allowed: + • Any memory mapped address. + + @param dest_addr + The dest_addr parameter specifies the destination address of the PDMA + transfer. You must ensure that this matches with the DMA destination + configured for the selected channel. + For DMA transfers from memory to MSS peripheral, the following dest_addr parameter values are allowed: + • PDMA_SPI0_TX_REGISTER + • PDMA_SPI1_TX_REGISTER + • PDMA_UART0_TX_REGISTER + • PDMA_UART1_TX_REGISTER + • PDMA_ACE_SSE_DATAIN + For DMA transfers from memory to FPGA fabric peripheral, the following + dest_addr parameter values are allowed: + • An address in the FPGA fabric address space (0x40050000-0x400FFFFF) + For DMA transfers from MSS peripheral to memory, or from FPGA fabric + peripheral to memory, or from memory to memory, the following dest_addr + parameter values are allowed: + • Any memory mapped address. + + @param transfer_count + The transfer_count parameter specifies the number of transfers to be + performed. It is the number of bytes to transfer if the PDMA channel is + configured for byte transfer, the number of half-words to transfer if the + PDMA channel is configured for half-word transfer, or the number of words + to transfer if the PDMA channel is configured for word transfer. + + Example: + @code + PDMA_start + ( + PDMA_CHANNEL_3, + PDMA_SPI1_RX_REGISTER, + (uint32_t)slave_rx_buffer, + sizeof(slave_rx_buffer) + ); + @endcode + */ +void PDMA_start +( + pdma_channel_id_t channel_id, + uint32_t src_addr, + uint32_t dest_addr, + uint16_t transfer_count +); + +/***************************************************************************//** + The PDMA_load_next_buffer() function sets the next buffer to be transferred. + This function is called after a transfer has been initiated using the + PDMA_start() function. Its purpose is to keep feeding a PDMA channel with data + buffers. + + @param channel_id + The channel_id parameter identifies the PDMA channel used by the function. + + @param src_addr + The src_addr parameter specifies the address location of the data to be + transferred. You must ensure that this source address is consistent with the + DMA source configured for the selected channel using the PDMA_configure() + function. + For DMA transfers from MSS peripheral to memory, the following src_addr parameter values are allowed: + • PDMA_SPI0_RX_REGISTER + • PDMA_SPI1_RX_REGISTER + • PDMA_UART0_RX_REGISTER + • PDMA_UART1_RX_REGISTER + • PDMA_ACE_PPE_DATAOUT + For DMA transfers from FPGA fabric peripheral to memory, the following src_addr parameter values are allowed: + • An address in the FPGA fabric address space (0x40050000-0x400FFFFF) + For DMA transfers from memory to MSS peripheral, or from memory to FPGA fabric peripheral, or from memory to memory, the following src_addr parameter values are allowed: + • Any memory mapped address. + + @param dest_addr + The dest_addr parameter specifies the destination address of the PDMA + transfer. You must ensure that this matches with the DMA destination + configured for the selected channel. + For DMA transfers from memory to MSS peripheral, the following dest_addr parameter values are allowed: + • PDMA_SPI0_TX_REGISTER + • PDMA_SPI1_TX_REGISTER + • PDMA_UART0_TX_REGISTER + • PDMA_UART1_TX_REGISTER + • PDMA_ACE_SSE_DATAIN + For DMA transfers from memory to FPGA fabric peripheral, the following dest_addr parameter values are allowed: + • An address in the FPGA fabric address space (0x40050000-0x400FFFFF) + For DMA transfers from MSS peripheral to memory, or from FPGA fabric peripheral to memory, or from memory to memory, the following dest_addr parameter values are allowed: + • Any memory mapped address. + + @param transfer_count + The transfer_count parameter specifies the number of transfers to be + performed. It is the number of bytes to transfer if the PDMA channel is + configured for byte transfer, the number of half-words to transfer if the + PDMA channel is configured for half-word transfer or the number of words to + transfer if the PDMA channel is configured for word transfer. + + Example: + @code + void write_cmd_data + ( + mss_spi_instance_t * this_spi, + const uint8_t * cmd_buffer, + uint16_t cmd_byte_size, + uint8_t * data_buffer, + uint16_t data_byte_size + ) + { + uint32_t transfer_size; + + transfer_size = cmd_byte_size + data_byte_size; + + MSS_SPI_disable( this_spi ); + MSS_SPI_set_transfer_byte_count( this_spi, transfer_size ); + + PDMA_start + ( + PDMA_CHANNEL_0, + (uint32_t)cmd_buffer, + PDMA_SPI1_TX_REGISTER, + cmd_byte_size + ); + + PDMA_load_next_buffer + ( + PDMA_CHANNEL_0, + (uint32_t)data_buffer, + PDMA_SPI1_TX_REGISTER, + data_byte_size + ); + + MSS_SPI_enable( this_spi ); + + while ( !MSS_SPI_tx_done(this_spi) ) + { + ; + } + } + @endcode + */ +void PDMA_load_next_buffer +( + pdma_channel_id_t channel_id, + uint32_t src_addr, + uint32_t dest_addr, + uint16_t transfer_count +); + +/***************************************************************************//** + The PDMA_status() function returns the status of a DMA channel. + The returned value indicates if transfers have been completed using buffer A + or buffer B of the PDMA hardware block. + + @param channel_id + The channel_id parameter identifies the PDMA channel used by the function. + + @return + bit 0 of the return value indicates if buffer A has been trasnfered. It is + set to 1 if the transfer has completed. + bit 1 of the return value indicates if buffer B has been transfered. It is + set to 1 if the transfer has completed. + */ +uint32_t PDMA_status +( + pdma_channel_id_t channel_id +); + +/***************************************************************************//** + The PDMA_pause() function temporarily pauses a PDMA transfer taking place on + the specified PDMA channel. The transfer can later be resumed by using the + PDMA_resume() function. + + @param channel_id + The channel_id parameter identifies the PDMA channel used by the function. + */ +static __INLINE void PDMA_pause( pdma_channel_id_t channel_id ) +{ + PDMA->CHANNEL[channel_id].CRTL |= PDMA_PAUSE_MASK; +} + +/***************************************************************************//** + The PDMA_resume() function resumes a transfer previously paused using the + PDMA_pause() function. + + @param channel_id The channel_id parameter identifies the PDMA channel + used by the function. + */ +static __INLINE void PDMA_resume( pdma_channel_id_t channel_id ) +{ + PDMA->CHANNEL[channel_id].CRTL &= ~PDMA_PAUSE_MASK; +} + +/***************************************************************************//** + The PDMA_enable_irq() enables the PDMA hardware to generate an interrupt when + a DMA transfer completes on the specified PDMA channel. This function also + enables the PDMA interrupt in the Cortex-M3 interrupt controller. + + @param channel_id + The channel_id parameter identifies the PDMA channel used by the function. + */ +void PDMA_enable_irq( pdma_channel_id_t channel_id ); + +/***************************************************************************//** + The PDMA_disable_irq() disables interrupts for a specific PDMA channel. + + @param channel_id + The channel_id parameter identifies the PDMA channel used by the function. + */ +static __INLINE void PDMA_disable_irq( pdma_channel_id_t channel_id ) +{ + PDMA->CHANNEL[channel_id].CRTL &= ~PDMA_IRQ_ENABLE_MASK; +} + +/***************************************************************************//** + The PDMA_set_irq_handler() function registers a handler function for + interrupts generated on the completion of a transfer on a specific PDMA + channel. This function also enables the PDMA interrupt both in the PDMA + controller and in the Cortex-M3 interrupt controller. + + @param channel_id + The channel_id parameter identifies the PDMA channel used by the function. + + @param handler + The handler parameter is a pointer to the function that will be called when + a transfer completes on the PDMA channel identified by channel_id and the + interrupt is enabled for that channel. + + Example: + @code + void slave_dma_irq_handler( void ) + { + if ( g_spi1_rx_buffer[2] == 0x99 ) + { + PDMA_load_next_buffer + ( + PDMA_CHANNEL_0, + (uint32_t)g_spi1_tx_buffer_b, + PDMA_SPI1_TX_REGISTER, + sizeof(g_spi1_tx_buffer_b) + ); + } + PDMA_disable_irq( PDMA_CHANNEL_3 ); + } + + void setup_dma( void ) + { + PDMA_init(); + PDMA_configure + ( + PDMA_CHANNEL_0, + PDMA_TO_SPI_1, + PDMA_LOW_PRIORITY | PDMA_BYTE_TRANSFER | PDMA_INC_SRC_ONE_BYTE + ); + PDMA_configure + ( + PDMA_CHANNEL_3, + PDMA_FROM_SPI_1, + PDMA_HIGH_PRIORITY | PDMA_BYTE_TRANSFER | PDMA_INC_DEST_ONE_BYTE + ); + PDMA_set_irq_handler( PDMA_CHANNEL_3, slave_dma_irq_handler ); + PDMA_start( PDMA_CHANNEL_3, PDMA_SPI1_RX_REGISTER, (uint32_t)g_spi1_rx_buffer, 3 ); + } + @endcode + */ +void PDMA_set_irq_handler +( + pdma_channel_id_t channel_id, + pdma_channel_isr_t handler +); + +/***************************************************************************//** + The PDMA_clear_irq() function clears interrupts for a specific PDMA channel. + This function also clears the PDMA interrupt in the Cortex-M3 NVIC. + + @param channel_id + The channel_id parameter identifies the PDMA channel used by the function. + */ +void PDMA_clear_irq +( + pdma_channel_id_t channel_id +); + +#ifdef __cplusplus +} +#endif + +#endif /* __MSS_PERIPHERAL_DMA_H_ */ diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_spi/mss_spi.c b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_spi/mss_spi.c new file mode 100644 index 000000000..e5992301f --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_spi/mss_spi.c @@ -0,0 +1,610 @@ +/******************************************************************************* + * (c) Copyright 2008 Actel Corporation. All rights reserved. + * + * SmartFusion microcontroller subsystem SPI bare metal software driver + * implementation. + * + * SVN $Revision: 2176 $ + * SVN $Date: 2010-02-15 21:04:22 +0000 (Mon, 15 Feb 2010) $ + */ +#include "mss_spi.h" +#include "../../CMSIS/mss_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************************************************************//** + MSS SPI can operate as master or slave. + */ +#define MSS_SPI_MODE_SLAVE (uint32_t)0 +#define MSS_SPI_MODE_MASTER (uint32_t)1 + +/***************************************************************************//** + * Mask of transfer protocol and SPO, SPH bits within control register. + */ +#define PROTOCOL_MODE_MASK (uint32_t)0x030000C0 + +/***************************************************************************//** + * Mask of theframe count bits within the SPI control register. + */ +#define TXRXDFCOUNT_MASK (uint32_t)0x00FFFF00 +#define TXRXDFCOUNT_SHIFT (uint32_t)8 + +/***************************************************************************//** + * SPI hardware FIFO depth. + */ +#define RX_FIFO_SIZE 4u + +/***************************************************************************//** + Marker used to detect that the configuration has not been selected for a + specific slave when operating as a master. + */ +#define NOT_CONFIGURED 0xFFFFFFFF + +/***************************************************************************//** + * SPI instance data structures for SPI0 and SPI1. A pointer to these data + * structures must be used as first parameter to any of the SPI driver functions + * to identify the SPI hardware block that will perform the requested operation. + */ +mss_spi_instance_t g_mss_spi0; +mss_spi_instance_t g_mss_spi1; + +/***************************************************************************//** + SPI0 interrupt service routine + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void SPI0_IRQHandler( void ); +#else +void SPI0_IRQHandler( void ); +#endif + +/***************************************************************************//** + SPI1 interrupt service routine + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void SPI1_IRQHandler( void ); +#else +void SPI1_IRQHandler( void ); +#endif + +/***************************************************************************//** + * MSS_SPI_init() + * See "mss_spi.h" for details of how to use this function. + */ +void MSS_SPI_init +( + mss_spi_instance_t * this_spi +) +{ + uint16_t i; + + ASSERT( (this_spi == &g_mss_spi0) || (this_spi == &g_mss_spi1) ); + + if (this_spi == &g_mss_spi0) + { + this_spi->hw_reg = SPI0; + this_spi->hw_reg_bit = SPI0_BITBAND; + this_spi->irqn = SPI0_IRQn; + + /* reset SPI0 */ + SYSREG->SOFT_RST_CR |= SYSREG_SPI0_SOFTRESET_MASK; + /* Clear any previously pended SPI0 interrupt */ + NVIC_ClearPendingIRQ( SPI0_IRQn ); + /* Take SPI0 out of reset. */ + SYSREG->SOFT_RST_CR &= ~SYSREG_SPI0_SOFTRESET_MASK; + } + else + { + this_spi->hw_reg = SPI1; + this_spi->hw_reg_bit = SPI1_BITBAND; + this_spi->irqn = SPI1_IRQn; + + /* reset SPI1 */ + SYSREG->SOFT_RST_CR |= SYSREG_SPI1_SOFTRESET_MASK; + /* Clear any previously pended SPI1 interrupt */ + NVIC_ClearPendingIRQ( SPI1_IRQn ); + /* Take SPI1 out of reset. */ + SYSREG->SOFT_RST_CR &= ~SYSREG_SPI1_SOFTRESET_MASK; + } + + this_spi->frame_rx_handler = 0U; + this_spi->slave_tx_frame = 0U; + + this_spi->block_rx_handler = 0U; + + this_spi->slave_tx_buffer = 0U; + this_spi->slave_tx_size = 0U; + this_spi->slave_tx_idx = 0U; + + for ( i = 0u; i < (uint16_t)MSS_SPI_MAX_NB_OF_SLAVES; ++i ) + { + this_spi->slaves_cfg[i].ctrl_reg = NOT_CONFIGURED; + } +} + +/***************************************************************************//** + * MSS_SPI_configure_slave_mode() + * See "mss_spi.h" for details of how to use this function. + */ +void MSS_SPI_configure_slave_mode +( + mss_spi_instance_t * this_spi, + mss_spi_protocol_mode_t protocol_mode, + mss_spi_pclk_div_t clk_rate, + uint8_t frame_bit_length +) +{ + ASSERT( (this_spi == &g_mss_spi0) || (this_spi == &g_mss_spi1) ); + ASSERT( frame_bit_length <= 32 ); + + /* Set the mode. */ + this_spi->hw_reg_bit->CTRL_MASTER = MSS_SPI_MODE_SLAVE; + + /* Set the clock rate. */ + this_spi->hw_reg_bit->CTRL_ENABLE = 0U; + this_spi->hw_reg->CONTROL = (this_spi->hw_reg->CONTROL & ~PROTOCOL_MODE_MASK) | (uint32_t)protocol_mode; + this_spi->hw_reg->CLK_GEN = (uint32_t)clk_rate; + + /* Set default frame size to byte size and number of data frames to 1. */ + this_spi->hw_reg->CONTROL = (this_spi->hw_reg->CONTROL & ~TXRXDFCOUNT_MASK) | ((uint32_t)1 << TXRXDFCOUNT_SHIFT); + this_spi->hw_reg->TXRXDF_SIZE = frame_bit_length; + this_spi->hw_reg_bit->CTRL_ENABLE = 1U; +} + +/***************************************************************************//** + * MSS_SPI_configure_master_mode() + * See "mss_spi.h" for details of how to use this function. + */ +void MSS_SPI_configure_master_mode +( + mss_spi_instance_t * this_spi, + mss_spi_slave_t slave, + mss_spi_protocol_mode_t protocol_mode, + mss_spi_pclk_div_t clk_rate, + uint8_t frame_bit_length +) +{ + ASSERT( (this_spi == &g_mss_spi0) || (this_spi == &g_mss_spi1) ); + ASSERT( slave < MSS_SPI_MAX_NB_OF_SLAVES ); + ASSERT( frame_bit_length <= 32 ); + + /* Set the mode. */ + this_spi->hw_reg_bit->CTRL_ENABLE = 0U; + this_spi->hw_reg_bit->CTRL_MASTER = MSS_SPI_MODE_MASTER; + this_spi->hw_reg_bit->CTRL_ENABLE = 1U; + + /* + * Keep track of the required register configuration for this slave. These + * values will be used by the MSS_SPI_set_slave_select() function to configure + * the master to match the slave being selected. + */ + if ( slave < MSS_SPI_MAX_NB_OF_SLAVES ) + { + this_spi->slaves_cfg[slave].ctrl_reg = 0x00000002uL | (uint32_t)protocol_mode | ((uint32_t)1 << TXRXDFCOUNT_SHIFT); + this_spi->slaves_cfg[slave].txrxdf_size_reg = frame_bit_length; + this_spi->slaves_cfg[slave].clk_gen = (uint8_t)clk_rate; + } +} + +/***************************************************************************//** + * MSS_SPI_set_slave_select() + * See "mss_spi.h" for details of how to use this function. + */ +void MSS_SPI_set_slave_select +( + mss_spi_instance_t * this_spi, + mss_spi_slave_t slave +) +{ + ASSERT( (this_spi == &g_mss_spi0) || (this_spi == &g_mss_spi1) ); + + /* This function is only intended to be used with an SPI master. */ + ASSERT( this_spi->hw_reg_bit->CTRL_MASTER == MSS_SPI_MODE_MASTER ); + ASSERT( this_spi->slaves_cfg[slave].ctrl_reg != NOT_CONFIGURED ); + + /* Set the clock rate. */ + this_spi->hw_reg_bit->CTRL_ENABLE = 0U; + this_spi->hw_reg->CONTROL = this_spi->slaves_cfg[slave].ctrl_reg; + this_spi->hw_reg->CLK_GEN = this_spi->slaves_cfg[slave].clk_gen; + this_spi->hw_reg->TXRXDF_SIZE = this_spi->slaves_cfg[slave].txrxdf_size_reg; + this_spi->hw_reg_bit->CTRL_ENABLE = 1U; + + /* Set slave select */ + this_spi->hw_reg->SLAVE_SELECT |= ((uint32_t)1 << (uint32_t)slave); +} + +/***************************************************************************//** + * MSS_SPI_clear_slave_select() + * See "mss_spi.h" for details of how to use this function. + */ +void MSS_SPI_clear_slave_select +( + mss_spi_instance_t * this_spi, + mss_spi_slave_t slave +) +{ + ASSERT( (this_spi == &g_mss_spi0) || (this_spi == &g_mss_spi1) ); + + /* This function is only intended to be used with an SPI master. */ + ASSERT( this_spi->hw_reg_bit->CTRL_MASTER == MSS_SPI_MODE_MASTER ); + + this_spi->hw_reg->SLAVE_SELECT &= ~((uint32_t)1 << (uint32_t)slave); +} + +/***************************************************************************//** + * MSS_SPI_transfer_frame() + * See "mss_spi.h" for details of how to use this function. + */ +uint32_t MSS_SPI_transfer_frame +( + mss_spi_instance_t * this_spi, + uint32_t tx_bits +) +{ + volatile uint32_t dummy; + + ASSERT( (this_spi == &g_mss_spi0) || (this_spi == &g_mss_spi1) ); + + /* This function is only intended to be used with an SPI master. */ + ASSERT( this_spi->hw_reg_bit->CTRL_MASTER == MSS_SPI_MODE_MASTER ); + + /* Flush Rx FIFO. */ + while ( this_spi->hw_reg_bit->STATUS_RX_RDY == 1U ) + { + dummy = this_spi->hw_reg->RX_DATA; + dummy = dummy; /* Prevent Lint warning. */ + } + + /* Send frame. */ + this_spi->hw_reg->TX_DATA = tx_bits; + + /* Wait for frame Tx to complete. */ + while ( this_spi->hw_reg_bit->STATUS_TX_DONE == 0U ) + { + ; + } + + /* Read received frame. */ + /* Wait for Rx complete. */ + while ( this_spi->hw_reg_bit->STATUS_RX_RDY == 0U ) + { + ; + } + /* Return Rx data. */ + return( this_spi->hw_reg->RX_DATA ); +} + + +/***************************************************************************//** + * MSS_SPI_transfer_block() + * See "mss_spi.h" for details of how to use this function. + */ +void MSS_SPI_transfer_block +( + mss_spi_instance_t * this_spi, + const uint8_t * cmd_buffer, + uint16_t cmd_byte_size, + uint8_t * rd_buffer, + uint16_t rd_byte_size +) +{ + uint16_t transfer_idx = 0U; + uint16_t tx_idx; + uint16_t rx_idx; + uint32_t frame_count; + volatile uint32_t rx_raw; + uint16_t transit = 0U; + + uint16_t transfer_size; /* Total number of bytes transfered. */ + + ASSERT( (this_spi == &g_mss_spi0) || (this_spi == &g_mss_spi1) ); + + /* This function is only intended to be used with an SPI master. */ + ASSERT( this_spi->hw_reg_bit->CTRL_MASTER == MSS_SPI_MODE_MASTER ); + + /* Compute number of bytes to transfer. */ + transfer_size = cmd_byte_size + rd_byte_size; + + /* Adjust to 1 byte transfer to cater for DMA transfers. */ + if ( transfer_size == 0U ) + { + frame_count = 1U; + } + else + { + frame_count = transfer_size; + } + + /* Set frame size to 8 bits and the frame count to the tansfer size. */ + this_spi->hw_reg_bit->CTRL_ENABLE = 0U; + this_spi->hw_reg->CONTROL = (this_spi->hw_reg->CONTROL & ~TXRXDFCOUNT_MASK) | ( (frame_count << TXRXDFCOUNT_SHIFT) & TXRXDFCOUNT_MASK); + this_spi->hw_reg->TXRXDF_SIZE = 8U; + this_spi->hw_reg_bit->CTRL_ENABLE = 1U; + + /* Flush the receive FIFO. */ + while ( !this_spi->hw_reg_bit->STATUS_RX_FIFO_EMPTY ) + { + rx_raw = this_spi->hw_reg->RX_DATA; + } + + tx_idx = 0u; + rx_idx = 0u; + if ( tx_idx < cmd_byte_size ) + { + this_spi->hw_reg->TX_DATA = cmd_buffer[tx_idx]; + ++tx_idx; + ++transit; + } + else + { + if ( tx_idx < transfer_size ) + { + this_spi->hw_reg->TX_DATA = 0x00U; + ++tx_idx; + ++transit; + } + } + /* Perform the remainder of the transfer by sending a byte every time a byte + * has been received. This should ensure that no Rx overflow can happen in + * case of an interrupt occurs during this function. */ + while ( transfer_idx < transfer_size ) + { + if ( !this_spi->hw_reg_bit->STATUS_RX_FIFO_EMPTY ) + { + /* Process received byte. */ + rx_raw = this_spi->hw_reg->RX_DATA; + if ( transfer_idx >= cmd_byte_size ) + { + if ( rx_idx < rd_byte_size ) + { + rd_buffer[rx_idx] = (uint8_t)rx_raw; + } + ++rx_idx; + } + ++transfer_idx; + --transit; + } + + if ( !this_spi->hw_reg_bit->STATUS_TX_FIFO_FULL ) + { + if (transit < RX_FIFO_SIZE) + { + /* Send another byte. */ + if ( tx_idx < cmd_byte_size ) + { + this_spi->hw_reg->TX_DATA = cmd_buffer[tx_idx]; + ++tx_idx; + ++transit; + } + else + { + if ( tx_idx < transfer_size ) + { + this_spi->hw_reg->TX_DATA = 0x00U; + ++tx_idx; + ++transit; + } + } + } + } + } +} + +/***************************************************************************//** + * MSS_SPI_set_frame_rx_handler() + * See "mss_spi.h" for details of how to use this function. + */ +void MSS_SPI_set_frame_rx_handler +( + mss_spi_instance_t * this_spi, + mss_spi_frame_rx_handler_t rx_handler +) +{ + ASSERT( (this_spi == &g_mss_spi0) || (this_spi == &g_mss_spi1) ); + + /* This function is only intended to be used with an SPI slave. */ + ASSERT( this_spi->hw_reg_bit->CTRL_MASTER == MSS_SPI_MODE_SLAVE ); + + /* Disable block Rx handler as they are mutually exclusive. */ + this_spi->block_rx_handler = 0U; + + /* Keep a copy of the pointer to the rx hnadler function. */ + this_spi->frame_rx_handler = rx_handler; + + /* Enable Rx interrupt. */ + this_spi->hw_reg_bit->CTRL_RX_INT_EN = 1U; + NVIC_EnableIRQ( this_spi->irqn ); +} + +/***************************************************************************//** + * MSS_SPI_set_slave_tx_frame() + * See "mss_spi.h" for details of how to use this function. + */ +void MSS_SPI_set_slave_tx_frame +( + mss_spi_instance_t * this_spi, + uint32_t frame_value +) +{ + ASSERT( (this_spi == &g_mss_spi0) || (this_spi == &g_mss_spi1) ); + + /* This function is only intended to be used with an SPI slave. */ + ASSERT( this_spi->hw_reg_bit->CTRL_MASTER == MSS_SPI_MODE_SLAVE ); + + /* Disable slave block tx buffer as it is mutually exclusive with frame + * level handling. */ + this_spi->slave_tx_buffer = 0U; + this_spi->slave_tx_size = 0U; + this_spi->slave_tx_idx = 0U; + + /* Keep a copy of the slave tx frame value. */ + this_spi->slave_tx_frame = frame_value; + + /* Load frame into Tx data register. */ + this_spi->hw_reg->TX_DATA = this_spi->slave_tx_frame; + + /* Enable Tx Done interrupt in order to reload the slave Tx frame after each + * time it has been sent. */ + this_spi->hw_reg_bit->CTRL_TX_INT_EN = 1U; + NVIC_EnableIRQ( this_spi->irqn ); +} + +/***************************************************************************//** + * MSS_SPI_set_slave_block_buffers() + * See "mss_spi.h" for details of how to use this function. + */ +void MSS_SPI_set_slave_block_buffers +( + mss_spi_instance_t * this_spi, + const uint8_t * tx_buffer, + uint32_t tx_buff_size, + uint8_t * rx_buffer, + uint32_t rx_buff_size, + mss_spi_block_rx_handler_t block_rx_handler +) +{ + uint32_t frame_count; + + ASSERT( (this_spi == &g_mss_spi0) || (this_spi == &g_mss_spi1) ); + + /* This function is only intended to be used with an SPI slave. */ + ASSERT( this_spi->hw_reg_bit->CTRL_MASTER == MSS_SPI_MODE_SLAVE ); + + /* Disable Rx frame handler as it is mutually exclusive with block rx handler. */ + this_spi->frame_rx_handler = 0U; + + /* Keep a copy of the pointer to the block rx handler function. */ + this_spi->block_rx_handler = block_rx_handler; + + this_spi->slave_rx_buffer = rx_buffer; + this_spi->slave_rx_size = rx_buff_size; + this_spi->slave_rx_idx = 0U; + + /**/ + this_spi->slave_tx_buffer = tx_buffer; + this_spi->slave_tx_size = tx_buff_size; + this_spi->slave_tx_idx = 0U; + + frame_count = rx_buff_size; + + /**/ + this_spi->hw_reg_bit->CTRL_ENABLE = 0U; + this_spi->hw_reg->CONTROL = (this_spi->hw_reg->CONTROL & ~TXRXDFCOUNT_MASK) | (frame_count << TXRXDFCOUNT_SHIFT); + this_spi->hw_reg->TXRXDF_SIZE = 8U; + this_spi->hw_reg_bit->CTRL_ENABLE = 1U; + + /* Load the transmit FIFO. */ + while ( !(this_spi->hw_reg_bit->STATUS_TX_FIFO_FULL) && ( this_spi->slave_tx_idx < this_spi->slave_tx_size ) ) + { + this_spi->hw_reg->TX_DATA = this_spi->slave_tx_buffer[this_spi->slave_tx_idx]; + ++this_spi->slave_tx_idx; + } + + /* Enable Rx interrupt. */ + this_spi->hw_reg_bit->CTRL_RX_INT_EN = 1U; + NVIC_EnableIRQ( this_spi->irqn ); +} + +/***************************************************************************//** + * SPI interrupt service routine. + */ +static void mss_spi_isr +( + mss_spi_instance_t * this_spi +) +{ + uint32_t rx_frame; + + ASSERT( (this_spi == &g_mss_spi0) || (this_spi == &g_mss_spi1) ); + + if ( this_spi->hw_reg_bit->MIS_RX_RDY ) + { + while( !this_spi->hw_reg_bit->STATUS_RX_FIFO_EMPTY ) + { + rx_frame = this_spi->hw_reg->RX_DATA; + if ( this_spi->frame_rx_handler != 0U ) + { + /* Single frame handling mode. */ + this_spi->frame_rx_handler( rx_frame ); + } + else + { + if ( this_spi->block_rx_handler != 0U ) + { + /* Block handling mode. */ + if ( this_spi->slave_rx_idx < this_spi->slave_rx_size ) + { + this_spi->slave_rx_buffer[this_spi->slave_rx_idx] = (uint8_t)rx_frame; + ++this_spi->slave_rx_idx; + if ( this_spi->slave_rx_idx == this_spi->slave_rx_size ) + { + (*this_spi->block_rx_handler)( this_spi->slave_rx_buffer, this_spi->slave_rx_size ); + } + } + } + } + + /* Feed transmit FIFO. */ + if ( !(this_spi->hw_reg_bit->STATUS_TX_FIFO_FULL) && ( this_spi->slave_tx_idx < this_spi->slave_tx_size ) ) + { + this_spi->hw_reg->TX_DATA = this_spi->slave_tx_buffer[this_spi->slave_tx_idx]; + ++this_spi->slave_tx_idx; + } + } + this_spi->hw_reg_bit->INT_CLEAR_RX_RDY = 1U; + } + + if ( this_spi->hw_reg_bit->MIS_TX_DONE ) + { + if ( this_spi->slave_tx_buffer != 0U ) + { + this_spi->hw_reg->TX_DATA = this_spi->slave_tx_buffer[this_spi->slave_tx_idx]; + ++this_spi->slave_tx_idx; + if ( this_spi->slave_tx_idx >= this_spi->slave_tx_size ) + { + this_spi->slave_tx_idx = 0U; + } + } + else + { + /* Reload slave tx frame into Tx data register. */ + this_spi->hw_reg->TX_DATA = this_spi->slave_tx_frame; + } + } +} + +/***************************************************************************//** + * SPIO interrupt service routine. + * Please note that the name of this ISR is defined as part of the SmartFusion + * CMSIS startup code. + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void SPI0_IRQHandler( void ) +#else +void SPI0_IRQHandler( void ) +#endif +{ + mss_spi_isr( &g_mss_spi0 ); + NVIC_ClearPendingIRQ( SPI0_IRQn ); +} + +/***************************************************************************//** + * SPI1 interrupt service routine. + * Please note that the name of this ISR is defined as part of the SmartFusion + * CMSIS startup code. + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void SPI1_IRQHandler( void ) +#else +void SPI1_IRQHandler( void ) +#endif +{ + mss_spi_isr( &g_mss_spi1 ); + NVIC_ClearPendingIRQ( SPI1_IRQn ); +} + +#ifdef __cplusplus +} +#endif + diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_spi/mss_spi.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_spi/mss_spi.h new file mode 100644 index 000000000..2b3617bc4 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_spi/mss_spi.h @@ -0,0 +1,1296 @@ +/***************************************************************************//** + * (c) Copyright 2008 Actel Corporation. All rights reserved. + * + * SmartFusion microcontroller subsystem SPI bare metal software driver public API. + * + * The microcontroller subsystem SPI driver provides functions for implementing + * SPI master or SPI slave operations. These operations can be one of two + * classes: SPI frame operation or block transfer operations. + * Frame operations allow transferring SPI frames from 4 to 32 bits long. Block + * operations allow transferring blocks of data organized as 8 bit bytes. + * + * SVN $Revision: 2189 $ + * SVN $Date: 2010-02-16 22:02:32 +0000 (Tue, 16 Feb 2010) $ + */ +/*=========================================================================*//** + @mainpage SmartFusion MSS SPI Bare Metal Driver. + + @section intro_sec Introduction + The SmartFusion™ microcontroller subsystem (MSS) includes two serial + peripheral interface SPI peripherals for serial communication. This driver + provides a set of functions for controlling the MSS SPIs as part of a bare + metal system where no operating system is available. These drivers can be + adapted for use as part of an operating system, but the implementation of the + adaptation layer between this driver and the operating system's driver model + is outside the scope of this driver. + + @section hw_dependencies Hardware Flow Dependencies + The configuration of all features of the MSS SPIs is covered by this driver + with the exception of the SmartFusion IOMUX configuration. SmartFusion allows + multiple non-concurrent uses of some external pins through IOMUX configuration. + This feature allows optimization of external pin usage by assigning external + pins for use by either the microcontroller subsystem or the FPGA fabric. The + MSS SPIs serial signals are routed through IOMUXes to the SmartFusion device + external pins. These IOMUXes are automatically configured correctly by the MSS + configurator tool in the hardware flow when the MSS SPIs are enabled in that + tool. You must ensure that the MSS SPIs are enabled by the MSS configurator + tool in the hardware flow; otherwise the serial inputs and outputs will not be + connected to the chip's external pins. For more information on IOMUX, refer to + the IOMUX section of the SmartFusion Datasheet. + The base address, register addresses and interrupt number assignment for the + MSS SPI blocks are defined as constants in the SmartFusion CMSIS-PAL. You must + ensure that the SmartFusion CMSIS-PAL is either included in the software tool + chain used to build your project or is included in your project. + + @section theory_op Theory of Operation + The MSS SPI driver functions are grouped into the following categories: + • Initialization + • Configuration for either master or slave operations + • SPI master frame transfer control + • SPI master block transfer control + • SPI slave frame transfer control + • SPI slave block transfer control + • DMA block transfer + Frame transfers allow the MSS SPI to write or read up to 32 bits of data in a + SPI transaction. For example, a frame transfer of 12 bits might be used to + read the result of an ADC conversion from a SPI analog to digital converter. + Block transfers allow the MSS SPI to write or read a number of bytes in a SPI + transaction. Block transfer transactions allow data transfers in multiples of + 8 bits (8, 16, 24, 32, 40…). Block transfers are typically used with byte + oriented devices like SPI FLASH devices. + + Initialization + The MSS SPI driver is initialized through a call to the MSS_SPI_init() + function. The MSS_SPI_init() function takes only one parameter, a pointer + to one of two global data structures used by the driver to store state + information for each MSS SPI. A pointer to these data structures is also + used as first parameter to any of the driver functions to identify which MSS + SPI will be used by the called function. The names of these two data + structures are g_mss_spi0 and g_mss_spi1. Therefore any call to an MSS SPI + driver function should be of the form MSS_SPI_function_name( &g_mss_spi0, ... ) + or MSS_SPI_function_name( &g_mss_spi1, ... ). + The MSS_SPI_init() function resets the specified MSS SPI hardware block and + clears any pending interrupts from that MSS SPI in the Cortex-M3 NVIC. + The MSS_SPI_init() function must be called before any other MSS SPI driver + functions can be called. + + Configuration + A MSS SPI block can operate either as a master or slave SPI device. There + are two distinct functions for configuring a MSS SPI block for master or + slave operations. + + Master configuration + The MSS_SPI_configure_master_mode() function configures the specified MSS + SPI block for operations as a SPI master. It must be called once for each + remote SPI slave device the MSS SPI block will communicate with. It is used + to provide the following information about each SPI slave’s communication + characteristics: + • The SPI protocol mode + • The SPI clock speed + • The frame bit length + This information is held by the driver and will be used to alter the + configuration of the MSS SPI block each time a slave is selected through a + call to MSS_SPI_set_slave_select(). The SPI protocol mode defines the + initial state of the clock signal at the start of a transaction and which + clock edge will be used to sample the data signal, or it defines whether the + SPI block will operate in TI synchronous serial mode or in NSC MICROWIRE mode. + + Slave configuration + The MSS_SPI_configure_slave_mode() function configures the specified MSS SPI + block for operations as a SPI slave. It configures the following SPI + communication characteristics: + • The SPI protocol mode + • The SPI clock speed + • The frame bit length + The SPI protocol mode defines the initial state of the clock signal at the + start of a transaction and which clock edge will be used to sample the data + signal, or it defines whether the SPI block will operate in TI synchronous + serial mode or in NSC MICROWIRE mode. + + SPI master frame transfer control + The following functions are used as part of SPI master frame transfers: + • MSS_SPI_set_slave_select() + • MSS_SPI_transfer_frame() + • MSS_SPI_clear_slave_select() + The master must first select the target slave through a call to + MSS_SPI_set_slave_select(). This causes the relevant slave select line to + become asserted while data is clocked out onto the SPI data line. + A call to is then made to function MSS_SPI_transfer_frame() specifying and + the value of the data frame to be sent. + The function MSS_SPI_clear_slave_select() can be used after the transfer is + complete to prevent this slave select line from being asserted during + subsequent SPI transactions. A call to this function is only required if the + master is communicating with multiple slave devices. + + SPI master block transfer control + The following functions are used as part of SPI master block transfers: + • MSS_SPI_set_slave_select() + • MSS_SPI_clear_slave_select() + • MSS_SPI_transfer_block() + The master must first select the target slave through a call to + MSS_SPI_set_slave_select(). This causes the relevant slave select line to + become asserted while data is clocked out onto the SPI data line. + Alternatively a GPIO can be used to control the state of the target slave + device’s chip select signal. + A call to is then made to function MSS_SPI_transfer_block (). The + parameters of this function specify: + • the number of bytes to be transmitted + • a pointer to the buffer containing the data to be transmitted + • the number of bytes to be received + • a pointer to the buffer where received data will be stored + The number of bytes to be transmitted can be set to zero to indicate that + the transfer is purely a block read transfer. The number of bytes to be + received can be set to zero to specify that the transfer is purely a block + write transfer. + The function MSS_SPI_clear_slave_select() can be used after the transfer is + complete to prevent this slave select line from being asserted during + subsequent SPI transactions. A call to this function is only required if the + master is communicating with multiple slave devices. + + SPI slave frame transfer control + The following functions are used as part of SPI slave frame transfers: + • MSS_SPI_set_slave_tx_frame() + • MSS_SPI_set_frame_rx_handler() + The MSS_SPI_set_slave_tx_frame() function specifies the frame data that will + be returned to the SPI master. The frame data specified through this + function is the value that will be read over the SPI bus by the remote SPI + master when it initiates a transaction. A call to MSS_SPI_set_slave_tx_frame() + is only required if the MSS SPI slave is the target of SPI read transactions, + i.e. if data is meant to be read from the SmartFusion device over SPI. + The MSS_SPI_set_frame_rx_handler() function specifies the receive handler + function that will called when a frame of data has been received by the MSS + SPI when it is configured as a slave. The receive handler function specified + through this call will process the frame data written, over the SPI bus, to + the MSS SPI slave by the remote SPI master. The receive handler function must + be implemented as part of the application. It is only required if the MSS SPI + slave is the target of SPI frame write transactions. + + SPI slave block transfer control + The following functions are used as part of SPI slave block transfers: + • MSS_SPI_set_slave_block_buffers() + The MSS_SPI_set_slave_block_buffers() function is used to configure a MSS SPI + slave for block transfer operations. It specifies: + • The buffer containing the data that will be returned to the remote SPI master + • The buffer where data received from the remote SPI master will be stored + • The handler function that will be called after the receive buffer is filled + + DMA block transfer control + The following functions are used as part of MSS SPI DMA transfers: + • MSS_SPI_disable() + • MSS_SPI_set_transfer_byte_count() + • MSS_SPI_enable() + • MSS_SPI_tx_done() + The MSS SPI must first be disabled through a call to function MSS_SPI_disable(). + The number of bytes to be transferred is then set through a call to function + MSS_SPI_set_transfer_byte_count(). The DMA transfer is then initiated by a call + to the MSS_PDMA_start() function provided by the MSS PDMA driver. The actual + DMA transfer will only start once the MSS SPI block has been re-enabled through + a call to MSS_SPI_enable(). The completion of the DMA driven SPI transfer can + be detected through a call to MSS_SPI_tx_done(). The direction of the SPI + transfer, write or read, depends on the DMA channel configuration. A SPI write + transfer occurs when the DMA channel is configured to write data to the MSS SPI + block. A SPI read transfer occurs when the DMA channel is configured to read data + from the MSS SPI block. + + *//*=========================================================================*/ +#ifndef MSS_SPI_H_ +#define MSS_SPI_H_ + +#include "../../CMSIS/a2fxxxm3.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************************************************************//** + This defines the function prototype that must be followed by MSS SPI slave + frame receive handler functions. These functions are registered with the MSS + SPI driver through the MSS_SPI_set_frame_rx_handler () function. + + Declaring and Implementing Slave Frame Receive Handler Functions: + Slave frame receive handler functions should follow the following prototype: + void slave_frame_receive_handler ( uint32_t rx_frame ); + The actual name of the receive handler is unimportant. You can use any name + of your choice for the receive frame handler. The rx_frame parameter will + contain the value of the received frame. + */ +typedef void (*mss_spi_frame_rx_handler_t)( uint32_t rx_frame ); + +/***************************************************************************//** + This defines the function prototype that must be followed by MSS SPI slave + block receive handler functions. These functions are registered with the MSS + SPI driver through the MSS_SPI_set_slave_block_buffers() function. + + Declaring and Implementing Slave Block Receive Handler Functions + Slave block receive handler functions should follow the following prototype: + void mss_spi_block_rx_handler ( uint8_t * rx_buff, uint16_t rx_size ); + The actual name of the receive handler is unimportant. You can use any name + of your choice for the receive frame handler. The rx_buff parameter will + contain a pointer to the start of the received block. The rx_size parameter + will contain the number of bytes of the received block. + + */ +typedef void (*mss_spi_block_rx_handler_t)( uint8_t * rx_buff, uint32_t rx_size ); + +/***************************************************************************//** + This enumeration is used to define the settings for the SPI protocol mode + bits, CPHA and CPOL. It is used as a parameter to the MSS_SPI_configure_master_mode() + and MSS_SPI_configure_slave_mode() functions. + + - MSS_SPI_MODE0: + Clock starts low, data read on clock's rising edge, data changes on + falling edge. + + - MSS_SPI_MODE1: + Clock starts low, data read on clock's falling edge, data changes on + rising edge. + + - MSS_SPI_MODE2: + Clock starts high, data read on clock's falling edge, data changes on + rising edge. + + - MSS_SPI_MODE3: + Clock starts high, data read on clock's rising edge, data changes on + falling edge. + + - MSS_TI_MODE: + TI syncronous serial mode. Slave select is pulsed at start of transfer. + + - MSS_NSC_MODE: + NSC Microwire mode. + */ +typedef enum __mss_spi_protocol_mode_t +{ + MSS_SPI_MODE0 = 0x00000000, + MSS_SPI_TI_MODE = 0x00000004, + MSS_SPI_NSC_MODE = 0x00000008, + MSS_SPI_MODE2 = 0x01000000, + MSS_SPI_MODE1 = 0x02000000, + MSS_SPI_MODE3 = 0x03000000 +} mss_spi_protocol_mode_t; + +/***************************************************************************//** + This enumeration specifies the divider to be applied to the the APB bus clock + in order to generate the SPI clock. It is used as parameter to the + MSS_SPI_configure_master_mode() and MSS_SPI_configure_slave_mode()functions. + */ + typedef enum __mss_spi_pclk_div_t + { + MSS_SPI_PCLK_DIV_2 = 0, + MSS_SPI_PCLK_DIV_4 = 1, + MSS_SPI_PCLK_DIV_8 = 2, + MSS_SPI_PCLK_DIV_16 = 3, + MSS_SPI_PCLK_DIV_32 = 4, + MSS_SPI_PCLK_DIV_64 = 5, + MSS_SPI_PCLK_DIV_128 = 6, + MSS_SPI_PCLK_DIV_256 = 7 +} mss_spi_pclk_div_t; + +/***************************************************************************//** + This enumeration is used to select a specific SPI slave device (0 to 7). It is + used as a parameter to the MSS_SPI_configure_master_mode(), + MSS_SPI_set_slave_select() and MSS_SPI_clear_slave_select () functions. + */ + typedef enum __mss_spi_slave_t + { + MSS_SPI_SLAVE_0 = 0, + MSS_SPI_SLAVE_1 = 1, + MSS_SPI_SLAVE_2 = 2, + MSS_SPI_SLAVE_3 = 3, + MSS_SPI_SLAVE_4 = 4, + MSS_SPI_SLAVE_5 = 5, + MSS_SPI_SLAVE_6 = 6, + MSS_SPI_SLAVE_7 = 7, + MSS_SPI_MAX_NB_OF_SLAVES = 8 +} mss_spi_slave_t; + +/***************************************************************************//** + This constant defines a frame size of 8 bits when configuring an MSS SPI to + perform block transfer data transactions. + It must be used as the value for the frame_bit_length parameter of function + MSS_SPI_configure_master_mode() when performing block transfers between the + MSS SPI master and the target SPI slave. + It must also be used as the value for the frame_bit_length parameter of + function MSS_SPI_configure_slave_mode() when performing block transfers + between the MSS SPI slave and the remote SPI master. + */ +#define MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE 8 + +/***************************************************************************//** + The mss_spi_slave_cfg_t holds the MSS SPI configuration that must be used to + communicate with a specific SPI slave. + */ +typedef struct __mss_spi_slave_cfg_t +{ + uint32_t ctrl_reg; + uint8_t txrxdf_size_reg; + uint8_t clk_gen; +} mss_spi_slave_cfg_t; + +/***************************************************************************//** + There is one instance of this structure for each of the microcontroller + subsystem's SPIs. Instances of this structure are used to identify a specific + SPI. A pointer to an instance of the mss_spi_instance_t structure is passed as + the first parameter to MSS SPI driver functions to identify which SPI should + perform the requested operation. + */ +typedef struct __mss_spi_instance_t +{ + /* CMSIS related defines identifying the SPI hardware. */ + SPI_TypeDef * hw_reg; /*!< Pointer to SPI registers. */ + SPI_BitBand_TypeDef * hw_reg_bit; /*!< Pointer to SPI registers bit band area. */ + IRQn_Type irqn; /*!< SPI's Cortex-M3 NVIC interrupt number. */ + + /* Internal transmit state: */ + const uint8_t * slave_tx_buffer; /*!< Pointer to slave transmit buffer. */ + uint32_t slave_tx_size; /*!< Size of slave transmit buffer. */ + uint32_t slave_tx_idx; /*!< Current index into slave transmit buffer. */ + + /* Internal receive state: */ + uint8_t * slave_rx_buffer; /*!< Pointer to buffer where data received by a slave will be stored. */ + uint32_t slave_rx_size; /*!< Slave receive buffer size. */ + uint32_t slave_rx_idx; /*!< Current index into slave receive buffer. */ + + /* Configuration for each target slave. */ + mss_spi_slave_cfg_t slaves_cfg[MSS_SPI_MAX_NB_OF_SLAVES]; + + /** Slave received frame handler: */ + mss_spi_frame_rx_handler_t frame_rx_handler; /*!< Pointer to function that will be called when a frame is received when the SPI block is configured as slave. */ + + uint32_t slave_tx_frame; /*!< Value of the data frame that will be transmited when the SPI block is configured as slave. */ + + /* Slave block rx handler: */ + mss_spi_block_rx_handler_t block_rx_handler; /*!< Pointer to the function that will be called when a data block has been received. */ + +} mss_spi_instance_t; + +/***************************************************************************//** + This instance of mss_spi_instance_t holds all data related to the operations + performed by MSS SPI 0. A pointer to g_mss_spi0 is passed as the first + parameter to MSS SPI driver functions to indicate that MSS SPI 0 should + perform the requested operation. + */ +extern mss_spi_instance_t g_mss_spi0; + +/***************************************************************************//** + This instance of mss_spi_instance_t holds all data related to the operations + performed by MSS SPI 1. A pointer to g_mss_spi1 is passed as the first + parameter to MSS SPI driver functions to indicate that MSS SPI 1 should + perform the requested operation. + */ +extern mss_spi_instance_t g_mss_spi1; + +/***************************************************************************//** + The MSS_SPI_init() function initializes and hardware and data structures of + one of the SmartFusion MSS SPIs. The MSS_SPI_init() function must be called + before any other MSS SPI driver functions can be called. + + @param this_spi + The this_spi parameter is a pointer to an mss_spi_instance_t structure + identifying the MSS SPI hardware block to be initialized. There are two such + data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and + MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 + or g_mss_spi1 global data structure defined within the SPI driver. + + Example: + @code + MSS_SPI_init( &g_mss_spi0 ); + @endcode + */ +void MSS_SPI_init +( + mss_spi_instance_t * this_spi +); + +/***************************************************************************//** + The MSS_SPI_configure_slave_mode() function configure a MSS SPI block for + operations as a slave SPI device. It configures the SPI hardware with the + selected SPI protocol mode and clock speed. + + @param this_spi + The this_spi parameter is a pointer to an mss_spi_instance_t structure + identifying the MSS SPI hardware block to be initialized. There are two such + data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and + MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 + or g_mss_spi1 global data structure defined within the SPI driver. + + @param protocol_mode + Serial peripheral interface operating mode. Allowed values are: + - MSS_SPI_MODE0 + - MSS_SPI_MODE1 + - MSS_SPI_MODE2 + - MSS_SPI_MODE3 + - MSS_TI_MODE + - MSS_NSC_MODE + + @param clk_rate + Divider value used to generate serial interface clock signal from PCLK. + Allowed values are: + - MSS_SPI_PCLK_DIV_2 + - MSS_SPI_PCLK_DIV_4 + - MSS_SPI_PCLK_DIV_8 + - MSS_SPI_PCLK_DIV_16 + - MSS_SPI_PCLK_DIV_32 + - MSS_SPI_PCLK_DIV_64 + - MSS_SPI_PCLK_DIV_128 + - MSS_SPI_PCLK_DIV_256 + + @param frame_bit_length + Number of bits making up the frame. The maximum frame length is 32 bits. You + must use the MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE constant as the value for + frame_bit_length when configuring the MSS SPI master for block transfer + transactions with the target SPI slave. + + Example: + @code + MSS_SPI_init( &g_mss_spi0 ); + MSS_SPI_configure_slave_mode + ( + &g_mss_spi0, + MSS_SPI_MODE2, + MSS_SPI_PCLK_DIV_64, + MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE + ); + @endcode + + */ +void MSS_SPI_configure_slave_mode +( + mss_spi_instance_t * this_spi, + mss_spi_protocol_mode_t protocol_mode, + mss_spi_pclk_div_t clk_rate, + uint8_t frame_bit_length +); + +/***************************************************************************//** + The MSS_SPI_configure_master_mode() function configures the protocol mode, + serial clock speed and frame size for a specific target SPI slave device. It + is used when the MSS SPI hardware block is used as a SPI master. This function + must be called once for each target SPI slave the SPI master is going to + communicate with. The SPI master hardware will be configured with the + configuration specified by this function during calls to + MSS_SPI_set_slave_select(). + + @param this_spi + The this_spi parameter is a pointer to an mss_spi_instance_t structure + identifying the MSS SPI hardware block to be initialized. There are two such + data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and + MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 + or g_mss_spi1 global data structure defined within the SPI driver. + + + @param slave + The slave parameter is used to identify a target SPI slave. The driver will + hold the MSS SPI master configuration required to communicate with this + slave, as specified by the other function parameters. Allowed values are: + • MSS_SPI_SLAVE_0 + • MSS_SPI_SLAVE_1 + • MSS_SPI_SLAVE_2 + • MSS_SPI_SLAVE_3 + • MSS_SPI_SLAVE_4 + • MSS_SPI_SLAVE_5 + • MSS_SPI_SLAVE_6 + • MSS_SPI_SLAVE_7 + + @param protocol_mode + Serial peripheral interface operating mode. Allowed values are: + • MSS_SPI_MODE0 + • MSS_SPI_MODE1 + • MSS_SPI_MODE2 + • MSS_SPI_MODE3 + • MSS_SPI_TI_MODE + • MSS_SPI_NSC_MODE + + @param clk_rate + Divider value used to generate serial interface clock signal from PCLK. + Allowed values are: + • MSS_SPI_PCLK_DIV_2 + • MSS_SPI_PCLK_DIV_4 + • MSS_SPI_PCLK_DIV_8 + • MSS_SPI_PCLK_DIV_16 + • MSS_SPI_PCLK_DIV_32 + • MSS_SPI_PCLK_DIV_64 + • MSS_SPI_PCLK_DIV_128 + • MSS_SPI_PCLK_DIV_256 + + @param frame_bit_length + Number of bits making up the frame. The maximum frame length is 32 bits. You + must use the MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE constant as the value for + frame_bit_length when configuring the MSS SPI master for block transfer + transactions with the target SPI slave. + + Example: + @code + MSS_SPI_init( &g_mss_spi0 ); + + MSS_SPI_configure_master_mode + ( + &g_mss_spi0, + MSS_SPI_SLAVE_0, + MSS_SPI_MODE2, + MSS_SPI_PCLK_DIV_64, + 12 + ); + + MSS_SPI_configure_master_mode + ( + &g_mss_spi0, + MSS_SPI_SLAVE_1, + MSS_SPI_TI_MODE, + MSS_SPI_PCLK_DIV_128, + MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE + ); + @endcode + */ +void MSS_SPI_configure_master_mode +( + mss_spi_instance_t * this_spi, + mss_spi_slave_t slave, + mss_spi_protocol_mode_t protocol_mode, + mss_spi_pclk_div_t clk_rate, + uint8_t frame_bit_length +); + +/*============================================================================== + * Master functions + *============================================================================*/ + +/***************************************************************************//** + The MSS_SPI_slave_select() function is used by a MSS SPI master to select a + specific slave. This function causes the relevant slave select signal to be + asserted. + + @param this_spi + The this_spi parameter is a pointer to an mss_spi_instance_t structure + identifying the MSS SPI hardware block to be initialized. There are two such + data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and + MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 + or g_mss_spi1 global data structure defined within the SPI driver. + + + @param slave + The slave parameter is one of mss_spi_slave_t enumerated constants + identifying a slave. + + Example: + @code + const uint8_t frame_size = 25; + const uint32_t master_tx_frame = 0x0100A0E1; + + MSS_SPI_init( &g_mss_spi0 ); + MSS_SPI_configure_master_mode + ( + &g_mss_spi0, + MSS_SPI_SLAVE_0, + MSS_SPI_MODE1, + MSS_SPI_PCLK_DIV_256, + frame_size + ); + + MSS_SPI_set_slave_select( &g_mss_spi0, MSS_SPI_SLAVE_0 ); + MSS_SPI_transfer_frame( &g_mss_spi0, master_tx_frame ); + MSS_SPI_clear_slave_select( &g_mss_spi0, MSS_SPI_SLAVE_0 ); + @endcode + */ +void MSS_SPI_set_slave_select +( + mss_spi_instance_t * this_spi, + mss_spi_slave_t slave +); + +/***************************************************************************//** + The MSS_SPI_clear_slave_select() function is used by a MSS SPI Master to + deselect a specific slave. This function causes the relevant slave select + signal to be de-asserted. + + @param this_spi + The this_spi parameter is a pointer to an mss_spi_instance_t structure + identifying the MSS SPI hardware block to be initialized. There are two such + data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and + MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 + or g_mss_spi1 global data structure defined within the SPI driver. + + + @param slave + The slave parameter is one of mss_spi_slave_t enumerated constants + identifying a slave. + + Example: + @code + const uint8_t frame_size = 25; + const uint32_t master_tx_frame = 0x0100A0E1; + + MSS_SPI_init( &g_mss_spi0 ); + MSS_SPI_configure_master_mode + ( + &g_mss_spi0, + MSS_SPI_SLAVE_0, + MSS_SPI_MODE1, + MSS_SPI_PCLK_DIV_256, + frame_size + ); + MSS_SPI_set_slave_select( &g_mss_spi0, MSS_SPI_SLAVE_0 ); + MSS_SPI_transfer_frame( &g_mss_spi0, master_tx_frame ); + MSS_SPI_clear_slave_select( &g_mss_spi0, MSS_SPI_SLAVE_0 ); + @endcode + */ +void MSS_SPI_clear_slave_select +( + mss_spi_instance_t * this_spi, + mss_spi_slave_t slave +); + +/***************************************************************************//** + The MSS_SPI_disable() function is used to temporarily disable a MSS SPI + hardware block. This function is typically used in conjunction with the + SPI_set_transfer_byte_count() function to setup a DMA controlled SPI transmit + transaction as the SPI_set_transfer_byte_count() function must only be used + when the MSS SPI hardware is disabled. + + @param this_spi + The this_spi parameter is a pointer to an mss_spi_instance_t structure + identifying the MSS SPI hardware block to be initialized. There are two such + data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and + MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 + or g_mss_spi1 global data structure defined within the SPI driver. + + Example: + @code + uint32_t transfer_size; + uint8_t tx_buffer[8] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + + transfer_size = sizeof(tx_buffer); + + MSS_SPI_disable( &g_mss_spi0 ); + MSS_SPI_set_transfer_byte_count( &g_mss_spi0, transfer_size ); + PDMA_start + ( + PDMA_CHANNEL_0, + (uint32_t)tx_buffer, + PDMA_SPI1_TX_REGISTER, + transfer_size + ); + MSS_SPI_enable( &g_mss_spi0 ); + + while ( !MSS_SPI_tx_done( &g_mss_spi0 ) ) + { + ; + } + @endcode + */ +static __INLINE void MSS_SPI_disable +( + mss_spi_instance_t * this_spi +) +{ + this_spi->hw_reg_bit->CTRL_ENABLE = 0; +} + +/***************************************************************************//** + The MSS_SPI_enable() function is used to re-enable a MSS SPI hardware block + after it was disabled using the SPI_disable() function. + + @param this_spi + The this_spi parameter is a pointer to an mss_spi_instance_t structure + identifying the MSS SPI hardware block to be initialized. There are two such + data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and + MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 + or g_mss_spi1 global data structure defined within the SPI driver. + + Example: + @code + uint32_t transfer_size; + uint8_t tx_buffer[8] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + + transfer_size = sizeof(tx_buffer); + + MSS_SPI_disable( &g_mss_spi0 ); + MSS_SPI_set_transfer_byte_count( &g_mss_spi0, transfer_size ); + PDMA_start + ( + PDMA_CHANNEL_0, + (uint32_t)tx_buffer, + PDMA_SPI1_TX_REGISTER, + transfer_size + ); + MSS_SPI_enable( &g_mss_spi0 ); + + while ( !MSS_SPI_tx_done( &g_mss_spi0 ) ) + { + ; + } + @endcode + */ +static __INLINE void MSS_SPI_enable +( + mss_spi_instance_t * this_spi +) +{ + this_spi->hw_reg_bit->CTRL_ENABLE = 1; +} + +/***************************************************************************//** + The MSS_SPI_set_transfer_byte_count() function is used as part of setting up + a SPI transfer using DMA. It specifies the number of bytes that must be + transferred before MSS_SPI_tx_done() indicates that the transfer is complete. + + @param this_spi + The this_spi parameter is a pointer to an mss_spi_instance_t structure + identifying the MSS SPI hardware block to be initialized. There are two such + data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and + MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 + or g_mss_spi1 global data structure defined within the SPI driver. + + + @param byte_count + The byte_count parameter specifies the number of bytes that must be + transferred by the SPI hardware block considering that a transaction has + been completed. + + Example: + @code + uint32_t transfer_size; + uint8_t tx_buffer[8] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + + transfer_size = sizeof(tx_buffer); + + MSS_SPI_disable( &g_mss_spi0 ); + + MSS_SPI_set_transfer_byte_count( &g_mss_spi0, transfer_size ); + + PDMA_start( PDMA_CHANNEL_0, (uint32_t)tx_buffer, 0x40011014, transfer_size ); + + MSS_SPI_enable( &g_mss_spi0 ); + + while ( !MSS_SPI_tx_done( &g_mss_spi0) ) + { + ; + } + @endcode + */ +static __INLINE void MSS_SPI_set_transfer_byte_count +( + mss_spi_instance_t * this_spi, + uint16_t byte_count +) +{ + const uint32_t TXRXDFCOUNT_SHIFT = 8U; + const uint32_t TXRXDFCOUNT_MASK = 0x00FFFF00U; + + this_spi->hw_reg->CONTROL = (this_spi->hw_reg->CONTROL & ~TXRXDFCOUNT_MASK) | ( (byte_count << TXRXDFCOUNT_SHIFT) & TXRXDFCOUNT_MASK); + this_spi->hw_reg->TXRXDF_SIZE = 8U; +} + +/***************************************************************************//** + The MSS_SPI_tx_done() function is used to find out if a DMA controlled transfer + has completed. + + @param this_spi + The this_spi parameter is a pointer to an mss_spi_instance_t structure + identifying the MSS SPI hardware block to be initialized. There are two such + data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and + MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 + or g_mss_spi1 global data structure defined within the SPI driver. + + Example: + @code + uint32_t transfer_size; + uint8_t tx_buffer[8] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + + transfer_size = sizeof(tx_buffer); + + MSS_SPI_disable( &g_mss_spi0 ); + + MSS_SPI_set_transfer_byte_count( &g_mss_spi0, transfer_size ); + + PDMA_start + ( + PDMA_CHANNEL_0, + (uint32_t)tx_buffer, + PDMA_SPI1_TX_REGISTER, + transfer_size + ); + + MSS_SPI_enable( &g_mss_spi0 ); + + while ( !MSS_SPI_tx_done(&g_mss_spi0) ) + { + ; + } + @endcode + */ +static __INLINE uint32_t MSS_SPI_tx_done +( + mss_spi_instance_t * this_spi +) +{ + return this_spi->hw_reg_bit->STATUS_TX_DONE; +} + +/***************************************************************************//** + The MSS_SPI_transfer_frame() function is used by a MSS SPI master to transmit + and receive a frame up to 32 bits long. This function is typically used for + transactions with a SPI slave where the number of transmit and receive bits is + not divisible by 8. + + @param this_spi + The this_spi parameter is a pointer to an mss_spi_instance_t structure + identifying the MSS SPI hardware block to be initialized. There are two such + data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and + MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 + or g_mss_spi1 global data structure defined within the SPI driver. + + + @param tx_bits + The tx_bits parameter is a 32 bits word containing the value that will be + transmitted. + Note: The bit length of the value to be transmitted to the slave must be + specified as the frame_bit_length parameter in a previous call to + the MSS_SPI_configure_master() function. + + @return + This function returns a 32 bits word containing the value that is received + from the slave. + + Example: + @code + const uint8_t frame_size = 25; + const uint32_t master_tx_frame = 0x0100A0E1; + uint32_t master_rx; + + MSS_SPI_init( &g_mss_spi0 ); + MSS_SPI_configure_master_mode + ( + &g_mss_spi0, + MSS_SPI_SLAVE_0, + MSS_SPI_MODE1, + MSS_SPI_PCLK_DIV_256, + frame_size + ); + + MSS_SPI_set_slave_select( &g_mss_spi0, MSS_SPI_SLAVE_0 ); + master_rx = MSS_SPI_transfer_frame( &g_mss_spi0, master_tx_frame ); + MSS_SPI_clear_slave_select( &g_mss_spi0, MSS_SPI_SLAVE_0 ); + @endcode + */ +uint32_t MSS_SPI_transfer_frame +( + mss_spi_instance_t * this_spi, + uint32_t tx_bits +); + +/***************************************************************************//** + The MSS_SPI_transfer_block() function is used by MSS SPI masters to transmit + and receive blocks of data organized as a specified number of bytes. It can be + used for: + • Writing a data block to a slave + • Reading a data block from a slave + • Sending a command to a slave followed by reading the outcome of the + command in a single SPI transaction. This function can be used alongside + Peripheral DMA functions to perform the actual moving to and from the SPI + hardware block using Peripheral DMA. + + @param this_spi + The this_spi parameter is a pointer to an mss_spi_instance_t structure + identifying the MSS SPI hardware block to be initialized. There are two such + data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and + MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 + or g_mss_spi1 global data structure defined within the SPI driver. + + + @param cmd_buffer + The cmd_buffer parameter is a pointer to the buffer containing the data that + will be sent by the master from the beginning of the transfer. This pointer + can be null (0) if the master does not need to send a command before reading + data or if the command part of the transfer is written to the SPI hardware + block using DMA. + + @param cmd_byte_size + The cmd_byte_size parameter specifies the number of bytes contained in + cmd_buffer that will be sent. A value of 0 indicates that no data needs to + be sent to the slave. A non-zero value while the cmd_buffer pointer is 0 is + used to indicate that the command data will be written to the SPI hardware + block using DMA. + + @param rd_buffer + The rd_buffer parameter is a pointer to the buffer where the data received + from the slave after the command has been sent will be stored. + + @param rd_byte_size + The rd_byte_size parameter specifies the number of bytes to be received from + the slave and stored in the rd_buffer. A value of 0 indicates that no data + is to be read from the slave. A non-zero value while the rd_buffer pointer + is null (0) is used to specify the receive size when using DMA to read from + the slave. + Note: All bytes received from the slave, including the bytes received + while the command is sent, will be read through DMA. + + Polled write transfer example: + @code + uint8_t master_tx_buffer[MASTER_TX_BUFFER] = + { + 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A + }; + MSS_SPI_init( &g_mss_spi0 ); + MSS_SPI_configure_master_mode + ( + &g_mss_spi0, + MSS_SPI_SLAVE_0, + MSS_SPI_MODE1, + MSS_SPI_PCLK_DIV_256, + MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE + ); + + MSS_SPI_set_slave_select( &g_mss_spi0, MSS_SPI_SLAVE_0 ); + MSS_SPI_transfer_block + ( + &g_mss_spi0, + master_tx_buffer, + sizeof(master_tx_buffer), + 0, + 0 + ); + MSS_SPI_clear_slave_select( &g_mss_spi0, MSS_SPI_SLAVE_0 ); + @endcode + + DMA transfer example: + In this example the transmit and receive buffers are not specified as part of + the call to MSS_SPI_transfer_block(). MSS_SPI_transfer_block() will only + prepare the MSS SPI hardware for a transfer. The MSS SPI transmit hardware + FIFO is filled using one DMA channel and a second DMA channel is used to read + the content of the MSS SPI receive hardware FIFO. The transmit and receive + buffers are specified by two separate calls to PDMA_start() to initiate DMA + transfers on the channel used for transmit data and the channel used for + receive data. + @code + uint8_t master_tx_buffer[MASTER_RX_BUFFER] = + { + 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA + }; + uint8_t slave_rx_buffer[MASTER_RX_BUFFER] = + { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A + }; + MSS_SPI_init( &g_mss_spi0 ); + + MSS_SPI_configure_master_mode + ( + &g_mss_spi0, + MSS_SPI_SLAVE_0, + MSS_SPI_MODE1, + MSS_SPI_PCLK_DIV_256, + MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE + ); + MSS_SPI_set_slave_select( &g_mss_spi0, MSS_SPI_SLAVE_0 ); + MSS_SPI_transfer_block( &g_mss_spi0, 0, 0, 0, 0 ); + PDMA_start + ( + PDMA_CHANNEL_1, + PDMA_SPI0_RX_REGISTER, + (uint32_t)master_rx_buffer, + sizeof(master_rx_buffer) + ); + PDMA_start + ( + PDMA_CHANNEL_2, + (uint32_t)master_tx_buffer, + PDMA_SPI0_TX_REGISTER, + sizeof(master_tx_buffer) + ); + while( PDMA_status(PDMA_CHANNEL_1) == 0 ) + { + ; + } + MSS_SPI_clear_slave_select( &g_mss_spi0, MSS_SPI_SLAVE_0 ); + @endcode + */ +void MSS_SPI_transfer_block +( + mss_spi_instance_t * this_spi, + const uint8_t * cmd_buffer, + uint16_t cmd_byte_size, + uint8_t * rd_buffer, + uint16_t rd_byte_size +); + +/*============================================================================== + * Slave functions + *============================================================================*/ + +/***************************************************************************//** + The MSS_SPI_set_frame_rx_handler() function is used by MSS SPI slaves to + specify the receive handler function that will be called by the MSS SPI driver + interrupt handler when a a frame of data is received by the MSS SPI slave. + + @param this_spi + The this_spi parameter is a pointer to an mss_spi_instance_t structure + identifying the MSS SPI hardware block to be initialized. There are two such + data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and + MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 + or g_mss_spi1 global data structure defined within the SPI driver. + + + @param rx_handler + The rx_handler parameter is a pointer to the frame receive handler that must + be called when a frame is received by the MSS SPI slave. + + Example: + @code + uint32_t g_slave_rx_frame = 0; + + void slave_frame_handler( uint32_t rx_frame ) + { + g_slave_rx_frame = rx_frame; + } + + int setup_slave( void ) + { + const uint16_t frame_size = 25; + MSS_SPI_init( &g_mss_spi1 ); + MSS_SPI_configure_slave_mode + ( + &g_mss_spi0, + MSS_SPI_MODE2, + MSS_SPI_PCLK_DIV_64, + frame_size + ); + MSS_SPI_set_frame_rx_handler( &g_mss_spi1, slave_frame_handler ); + } + @endcode + */ +void MSS_SPI_set_frame_rx_handler +( + mss_spi_instance_t * this_spi, + mss_spi_frame_rx_handler_t rx_handler +); + +/***************************************************************************//** + The MSS_SPI_set_slave_tx_frame() function is used by MSS SPI slaves to specify + the frame that will be transmitted when a transaction is initiated by the SPI + master. + + @param this_spi + The this_spi parameter is a pointer to an mss_spi_instance_t structure + identifying the MSS SPI hardware block to be initialized. There are two such + data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and + MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 + or g_mss_spi1 global data structure defined within the SPI driver. + + + @param frame_value + The frame_value parameter contains the value of the frame to be sent to the + master. + Note: The bit length of the value to be transmitted to the master must be + specified as the frame_bit_length parameter in a previous call to + the MSS_SPI_configure_slave() function. + + Example: + @code + const uint16_t frame_size = 25; + const uint32_t slave_tx_frame = 0x0110F761; + uint32_t master_rx; + + MSS_SPI_init( &g_mss_spi1 ); + MSS_SPI_configure_slave_mode + ( + &g_mss_spi0, + MSS_SPI_MODE2, + MSS_SPI_PCLK_DIV_64, + frame_size + ); + MSS_SPI_set_slave_tx_frame( &g_mss_spi1, slave_tx_frame ); + @endcode + */ +void MSS_SPI_set_slave_tx_frame +( + mss_spi_instance_t * this_spi, + uint32_t frame_value +); + +/***************************************************************************//** + The MSS_SPI_set_slave_block_buffers() function is used to configure an MSS + SPI slave for block transfer operations. It specifies one or more of the + following: + • The data that will be transmitted when accessed by a master. + • The buffer where data received from a master will be stored. + • The handler function that must be called after the receive buffer has been + filled. + • The number of bytes that must be received from the master before the receive + handler function is called. + These parameters allow the following use cases: + • Slave performing an action after receiving a block of data from a master + containing a command. The action will be performed by the receive handling + based on the content of the receive data buffer. + • Slave returning a block of data to the master. The type of information is + always the same but the actual values change over time. For example, + returning the voltage of a predefined set of analog inputs. + • Slave returning data based on a command contained in the first part of the + SPI transaction. For example, reading the voltage of the analog input + specified by the first data byte by the master. This is achieved by setting + the rx_buff_size parameter to the number of received bytes making up the + command. + + @param this_spi + The this_spi parameter is a pointer to an mss_spi_instance_t structure + identifying the MSS SPI hardware block to be initialized. There are two such + data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and + MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 + or g_mss_spi1 global data structure defined within the SPI driver. + + + @param tx_buffer + The tx_buffer parameter is a pointer to a buffer containing the data that + will be sent to the master. This parameter can be set to 0 if the MSS SPI + slave is not intended to be the target of SPI read transactions or if DMA + is used to transfer SPI read data into the MSS SPI slave. + + @param tx_buff_size + The tx_buff_size parameter specifies the number of bytes contained in the + tx_buffer. This parameter can be set to 0 if the MSS SPI slave is not + intended to be the target of SPI read transactions or if DMA is used to + transfer SPI read data into the MSS SPI slave. + + @param rx_buffer + The rx_buffer parameter is a pointer to the buffer where data received from + the master will be stored. This parameter can be set to 0 if the MSS SPI + slave is not intended to be the target of SPI write or write-read + transactions. It can also set to 0 if the MSS SPI slave uses DMA to handle + data written to it. + + @param rx_buff_size + The rx_buff_size parameter specifies the size of the receive buffer. It is + also the number of bytes that must be received before the receive handler + is called, if a receive handler is specified using the block_rx_handler + parameter. This parameter can be set to 0 if the MSS SPI slave is not + intended to be the target of SPI write or write-read transactions. It can + also set to 0 if the MSS SPI slave uses DMA to handle data written to it. + + @param block_rx_handler + The block_rx_handler parameter is a pointer to a function that will be + called when the receive buffer has been filled. This parameter can be set + to 0 if the MSS SPI slave is not intended to be the target of SPI write or + write-read transactions. It can also set to 0 if the MSS SPI slave uses DMA + to handle data written to it. + + Slave performing operation based on master command: + In this example the SPI slave is configured to receive 10 bytes of data or + command from the SPI slave and process the data received from the master. + @code + uint32_t nb_of_rx_handler_calls = 0; + + void spi1_block_rx_handler_b + ( + uint8_t * rx_buff, + uint16_t rx_size + ) + { + ++nb_of_rx_handler_calls; + } + + void setup_slave( void ) + { + uint8_t slave_rx_buffer[10] = + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + MSS_SPI_init( &g_mss_spi1 ); + MSS_SPI_configure_slave_mode + ( + &g_mss_spi0, + MSS_SPI_MODE2, + MSS_SPI_PCLK_DIV_64, + MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE + ); + + MSS_SPI_set_slave_block_buffers + ( + &g_mss_spi1, + 0, + 0, + slave_rx_buffer, + sizeof(master_tx_buffer), + spi1_block_rx_handler_b + ); + } + @endcode + + Slave responding to command example: + In this example the slave will return data based on a command sent by the + master. The first part of the transaction is handled using polled mode where + each byte returned to the master is written as part of the interrupt service + routine. The second part of the transaction, where the slave returns data + based on the command value, is sent using a DMA transfer initiated by the + receive handler. + @code + static uint8_t g_spi1_tx_buffer_b[SLAVE_TX_BUFFER_SIZE] = + { + 5, 6, 7, 8, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5 + }; + + void spi1_block_rx_handler + ( + uint8_t * rx_buff, + uint16_t rx_size + ) + { + if ( rx_buff[2] == 0x99 ) + { + PDMA_start + ( + PDMA_CHANNEL_0, + (uint32_t)g_spi1_tx_buffer_b, + 0x40011014, + sizeof(g_spi1_tx_buffer_b) + ); + } + } + + void setup_slave( void ) + { + uint8_t slave_preamble[8] = { 9, 10, 11, 12, 13, 14, 16, 16 }; + + MSS_SPI_init( &g_mss_spi1 ); + MSS_SPI_configure_slave_mode + ( + &g_mss_spi0, + MSS_SPI_MODE2, + MSS_SPI_PCLK_DIV_64, + MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE + ); + + PDMA_init(); + PDMA_configure + ( + PDMA_CHANNEL_0, + TO_SPI_1, + LOW_PRIORITY | BYTE_TRANSFER | INC_SRC_ONE_BYTE + ); + + MSS_SPI_set_slave_block_buffers + ( + &g_mss_spi1, + slave_preamble, + 4, + g_spi1_rx_buffer, + sizeof(g_spi1_rx_buffer), + spi1_block_rx_handler + ); + } + @endcode + */ +void MSS_SPI_set_slave_block_buffers +( + mss_spi_instance_t * this_spi, + const uint8_t * tx_buffer, + uint32_t tx_buff_size, + uint8_t * rx_buffer, + uint32_t rx_buff_size, + mss_spi_block_rx_handler_t block_rx_handler +); + +#ifdef __cplusplus +} +#endif + +#endif /* MSS_SPI_H_*/ diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_uart/mss_uart.c b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_uart/mss_uart.c new file mode 100644 index 000000000..7dbb6c010 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_uart/mss_uart.c @@ -0,0 +1,458 @@ +/******************************************************************************* + * (c) Copyright 2007 Actel Corporation. All rights reserved. + * + * SmartFusion Microcontroller Subsystem UART bare metal software driver + * implementation. + * + * SVN $Revision: 1898 $ + * SVN $Date: 2009-12-21 17:27:57 +0000 (Mon, 21 Dec 2009) $ + */ +#include "mss_uart.h" +#include "../../CMSIS/mss_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * defines + */ +#define TX_READY 0x01U +#define TX_COMPLETE 0U + +#define TX_FIFO_SIZE 16U + +#define FCR_TRIG_LEVEL_MASK 0xC0U + +#define IIRF_MASK 0x0FU + +/******************************************************************************* + * Possible values for Interrupt Identification Register Field. + */ +#define IIRF_MODEM_STATUS 0x00U +#define IIRF_THRE 0x02U +#define IIRF_RX_DATA 0x04U +#define IIRF_RX_LINE_STATUS 0x06U +#define IIRF_DATA_TIMEOUT 0x0CU + +/******************************************************************************* + * Cortex-M3 interrupt handler functions implemented as part of the MSS UART + * driver. + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void UART0_IRQHandler( void ); +#else +void UART0_IRQHandler( void ); +#endif + +#if defined(__GNUC__) +__attribute__((__interrupt__)) void UART1_IRQHandler( void ); +#else +void UART1_IRQHandler( void ); +#endif + +/******************************************************************************* + * Local functions. + */ +static void MSS_UART_isr( mss_uart_instance_t * this_uart ); + +/******************************************************************************* + * + */ +mss_uart_instance_t g_mss_uart0; +mss_uart_instance_t g_mss_uart1; + +/***************************************************************************//** + * UART_init. + * Initialises the UART with default configuration. + */ +void +MSS_UART_init +( + mss_uart_instance_t* this_uart, + uint32_t baud_rate, + uint8_t line_config +) +{ + uint16_t baud_value; + uint32_t pclk_freq; + + /* The driver expects g_mss_uart0 and g_mss_uart1 to be the only + * mss_uart_instance_t instances used to identfy UART0 and UART1. */ + ASSERT( (this_uart == &g_mss_uart0) || (this_uart == &g_mss_uart1) ); + + /* Force the value of the CMSIS global variables holding the various system + * clock frequencies to be updated. */ + SystemCoreClockUpdate(); + + if ( this_uart == &g_mss_uart0 ) + { + this_uart->hw_reg = UART0; + this_uart->hw_reg_bit = UART0_BITBAND; + this_uart->irqn = UART0_IRQn; + + pclk_freq = g_FrequencyPCLK0; + + /* reset UART0 */ + SYSREG->SOFT_RST_CR |= SYSREG_UART0_SOFTRESET_MASK; + /* Clear any previously pended UART0 interrupt */ + NVIC_ClearPendingIRQ( UART0_IRQn ); + /* Take UART0 out of reset. */ + SYSREG->SOFT_RST_CR &= ~SYSREG_UART0_SOFTRESET_MASK; + } + else + { + this_uart->hw_reg = UART1; + this_uart->hw_reg_bit = UART1_BITBAND; + this_uart->irqn = UART1_IRQn; + + pclk_freq = g_FrequencyPCLK1; + + /* Reset UART1 */ + SYSREG->SOFT_RST_CR |= SYSREG_UART1_SOFTRESET_MASK; + /* Clear any previously pended UART1 interrupt */ + NVIC_ClearPendingIRQ( UART1_IRQn ); + /* Take UART1 out of reset. */ + SYSREG->SOFT_RST_CR &= ~SYSREG_UART1_SOFTRESET_MASK; + } + + /* disable interrupts */ + this_uart->hw_reg->IER = 0U; + + /* + * Compute baud value based on requested baud rate and PCLK frequency. + * The baud value is computed using the following equation: + * baud_value = PCLK_Frequency / (baud_rate * 16) + * The baud value is rounded up or down depending on what would be the remainder + * of the divide by 16 operation. + */ + baud_value = (uint16_t)(pclk_freq / baud_rate); + if ( baud_value & 0x00000008U ) + { + /* remainder above 0.5 */ + baud_value = (baud_value >> 4U) + 1U; + } + else + { + /* remainder below 0.5 */ + baud_value = (baud_value >> 4U); + } + + /* set divisor latch */ + this_uart->hw_reg_bit->LCR_DLAB = (uint32_t)1; + + /* msb of baud value */ + this_uart->hw_reg->DMR = (uint8_t)(baud_value >> 8); + /* lsb of baud value */ + this_uart->hw_reg->DLR = (uint8_t)baud_value; + + /* reset divisor latch */ + this_uart->hw_reg_bit->LCR_DLAB = (uint32_t)0; + + /* set the line control register (bit length, stop bits, parity) */ + this_uart->hw_reg->LCR = line_config; + + /* FIFO configuration */ + this_uart->hw_reg->FCR = (uint8_t)MSS_UART_FIFO_SINGLE_BYTE; + + /* disable loopback */ + this_uart->hw_reg_bit->MCR_LOOP = (uint32_t)0; + + /* Instance setup */ + this_uart->tx_buff_size = TX_COMPLETE; + this_uart->tx_buffer = (const uint8_t *)0; + this_uart->tx_idx = 0U; + + this_uart->rx_handler = (mss_uart_rx_handler_t)0; +} + +/***************************************************************************//** + * See mss_uart.h for details of how to use this function. + */ +void +MSS_UART_polled_tx +( + mss_uart_instance_t * this_uart, + const uint8_t * pbuff, + uint32_t tx_size +) +{ + uint32_t char_idx; + uint32_t status; + + ASSERT( (this_uart == &g_mss_uart0) || (this_uart == &g_mss_uart1) ); + + for ( char_idx = 0U; char_idx < tx_size; char_idx++ ) + { + /* Wait for UART to become ready to transmit. */ + do { + status = this_uart->hw_reg_bit->LSR_THRE; + } while ( (status & TX_READY) == 0U ); + /* Send next character in the buffer. */ + this_uart->hw_reg->THR = pbuff[char_idx]; + } +} + +/***************************************************************************//** + * See mss_uart.h for details of how to use this function. + */ +void +MSS_UART_polled_tx_string +( + mss_uart_instance_t * this_uart, + const uint8_t * p_sz_string +) +{ + uint32_t char_idx; + uint32_t status; + + ASSERT( (this_uart == &g_mss_uart0) || (this_uart == &g_mss_uart1) ); + + char_idx = 0U; + + while ( p_sz_string[char_idx] != 0U ) + { + /* Wait for UART to become ready to transmit. */ + do { + status = this_uart->hw_reg_bit->LSR_THRE; + } while ( (status & TX_READY) == 0U); + /* Send next character in the buffer. */ + this_uart->hw_reg->THR = p_sz_string[char_idx]; + ++char_idx; + } +} + +/***************************************************************************//** + * See mss_uart.h for details of how to use this function. + */ +void +MSS_UART_irq_tx +( + mss_uart_instance_t * this_uart, + const uint8_t * pbuff, + uint32_t tx_size +) +{ + ASSERT( (this_uart == &g_mss_uart0) || (this_uart == &g_mss_uart1) ); + + if ( tx_size > 0U ) + { + /*Initialise the transmit info for the UART instance with the arguments.*/ + this_uart->tx_buffer = pbuff; + this_uart->tx_buff_size = tx_size; + this_uart->tx_idx = (uint16_t)0; + + /* enables TX interrupt */ + this_uart->hw_reg_bit->IER_ETBEI = (uint32_t)1; + + /* Enable UART instance interrupt in Cortex-M3 NVIC. */ + NVIC_EnableIRQ( this_uart->irqn ); + } +} + +/***************************************************************************//** + * See mss_uart.h for details of how to use this function. + */ +int8_t +MSS_UART_tx_complete +( + mss_uart_instance_t * this_uart +) +{ + int8_t ret_value = 0; + uint32_t transmit_empty = this_uart->hw_reg_bit->LSR_TEMT; + + ASSERT( (this_uart == &g_mss_uart0) || (this_uart == &g_mss_uart1) ); + + if ( ( TX_COMPLETE == this_uart->tx_buff_size ) && transmit_empty ) + { + ret_value = 1; + } + + return ret_value; +} + + +/***************************************************************************//** + * See mss_uart.h for details of how to use this function. + */ +size_t +MSS_UART_get_rx +( + mss_uart_instance_t * this_uart, + uint8_t * rx_buff, + size_t buff_size +) +{ + size_t rx_size = 0U; + + ASSERT( (this_uart == &g_mss_uart0) || (this_uart == &g_mss_uart1) ); + + while (( this_uart->hw_reg_bit->LSR_DR != 0U) && ( rx_size < buff_size ) ) + { + rx_buff[rx_size] = this_uart->hw_reg->RBR; + ++rx_size; + } + + return rx_size; +} + +/***************************************************************************//** + * Interrupt service routine triggered by the Transmitter Holding Register + * Empty (THRE) interrupt or Received Data Available (RDA). + * On THRE irq this routine will transmit the data from the transmit buffer. + * When all bytes are transmitted, this routine disables the THRE interrupt + * and resets the transmit counter. + * On RDA irq this routine will call the user's receive handler routine previously + * registered with the UART driver through a call to UART_set_rx_handler(). + */ +static void +MSS_UART_isr +( + mss_uart_instance_t * this_uart +) +{ + uint8_t iirf; + uint32_t tx_empty; + + ASSERT( (this_uart == &g_mss_uart0) || (this_uart == &g_mss_uart1) ); + + iirf = this_uart->hw_reg->IIR & IIRF_MASK; + + switch ( iirf ) + { + case IIRF_MODEM_STATUS: + break; + + case IIRF_THRE: /* Transmitter Holding Register Empty */ + tx_empty = this_uart->hw_reg_bit->LSR_TEMT; + + if ( tx_empty ) + { + uint32_t i; + uint32_t fill_size = TX_FIFO_SIZE; + uint32_t tx_remain = this_uart->tx_buff_size - this_uart->tx_idx; + if ( tx_remain < TX_FIFO_SIZE ) + { + fill_size = tx_remain; + } + /* Fill up FIFO */ + for ( i = 0U; i < fill_size; ++i ) + { + this_uart->hw_reg->THR = this_uart->tx_buffer[this_uart->tx_idx]; + ++this_uart->tx_idx; + } + } + else + { + this_uart->hw_reg->THR = this_uart->tx_buffer[this_uart->tx_idx]; + ++this_uart->tx_idx; + } + + if ( this_uart->tx_idx == this_uart->tx_buff_size ) + { + this_uart->tx_buff_size = TX_COMPLETE; + /* disables TX interrupt */ + this_uart->hw_reg_bit->IER_ETBEI = 0U; + } + break; + + case IIRF_RX_DATA: /* Received Data Available */ + case IIRF_DATA_TIMEOUT: + if (this_uart->rx_handler != 0) + { + (*(this_uart->rx_handler))(); + } + break; + + case IIRF_RX_LINE_STATUS: + break; + + default: + /* Disable other interrupts */ + this_uart->hw_reg_bit->IER_ELSI = 0U; + this_uart->hw_reg_bit->IER_EDSSI = 0U; + break; + } +} + +/***************************************************************************//** + * See mss_uart.h for details of how to use this function. + */ +void +MSS_UART_set_rx_handler +( + mss_uart_instance_t * this_uart, + mss_uart_rx_handler_t handler, + mss_uart_rx_trig_level_t trigger_level +) +{ + ASSERT( (this_uart == &g_mss_uart0) || (this_uart == &g_mss_uart1) ); + + this_uart->rx_handler = handler; + + /* Set the receive interrupt trigger level. */ + this_uart->hw_reg->FCR = (this_uart->hw_reg->FCR & (uint8_t)(~((uint8_t)FCR_TRIG_LEVEL_MASK))) | (uint8_t)trigger_level; + + /* Enable receive interrupt. */ + this_uart->hw_reg_bit->IER_ERBFI = 1U; + + /* Enable UART instance interrupt in Cortex-M3 NVIC. */ + NVIC_EnableIRQ( this_uart->irqn ); +} + +/***************************************************************************//** + * See mss_uart.h for details of how to use this function. + */ +void +MSS_UART_set_loopback +( + mss_uart_instance_t * this_uart, + mss_uart_loopback_t loopback +) +{ + ASSERT( (this_uart == &g_mss_uart0) || (this_uart == &g_mss_uart1) ); + + if ( loopback == MSS_UART_LOOPBACK_OFF ) + { + this_uart->hw_reg_bit->MCR_LOOP = 0U; + } + else + { + this_uart->hw_reg_bit->MCR_LOOP = 1U; + } +} + +/***************************************************************************//** + * UART0 interrupt service routine. + * UART0_IRQHandler is included within the Cortex-M3 vector table as part of the + * Fusion 2 CMSIS. + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void UART0_IRQHandler( void ) +#else +void UART0_IRQHandler( void ) +#endif +{ + MSS_UART_isr( &g_mss_uart0 ); + NVIC_ClearPendingIRQ( UART0_IRQn ); +} + +/***************************************************************************//** + * UART1 interrupt service routine. + * UART2_IRQHandler is included within the Cortex-M3 vector table as part of the + * Fusion 2 CMSIS. + */ +#if defined(__GNUC__) +__attribute__((__interrupt__)) void UART1_IRQHandler( void ) +#else +void UART1_IRQHandler( void ) +#endif +{ + MSS_UART_isr( &g_mss_uart1 ); + NVIC_ClearPendingIRQ( UART1_IRQn ); +} + +#ifdef __cplusplus +} +#endif diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_uart/mss_uart.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_uart/mss_uart.h new file mode 100644 index 000000000..3897a3c37 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_uart/mss_uart.h @@ -0,0 +1,626 @@ +/******************************************************************************* + * (c) Copyright 2007 Actel Corporation. All rights reserved. + * + * SmartFusion Microcontroller Subsystem UART bare metal software driver public API. + * + * SVN $Revision: 1942 $ + * SVN $Date: 2009-12-22 17:48:07 +0000 (Tue, 22 Dec 2009) $ + */ +/*=========================================================================*//** + @mainpage SmartFusion MSS UART Bare Metal Driver. + + @section intro_sec Introduction + The SmartFusion MicroController Subsystem (MSS) includes two UART peripherals + for serial communications. + This driver provides a set of functions for controlling the MSS UARTs as part + of a bare metal system where no operating system is available. These drivers + can be adapted for use as part of an operating system but the implementation + of the adaptation layer between this driver and the operating system's driver + model is outside the scope of this driver. + + @section hw_dependencies Hardware Flow Dependencies + The configuration of all features of the MSS UARTs is covered by this driver + with the exception of the SmartFusion IOMUX configuration. SmartFusion allows + multiple non-concurrent uses of some external pins through IOMUX configuration. + This feature allows optimization of external pin usage by assigning external + pins for use by either the microcontroller subsystem or the FPGA fabric. The + MSS UARTs serial signals are routed through IOMUXes to the SmartFusion device + external pins. These IOMUXes are configured automatically by the MSS + configurator tool in the hardware flow correctly when the MSS UARTs are enabled + in that tool. You must ensure that the MSS UARTs are enabled by the MSS + configurator tool in the hardware flow; otherwise the serial inputs and outputs + will not be connected to the chip's external pins. For more information on + IOMUX, refer to the IOMUX section of the SmartFusion Datasheet. + The base address, register addresses and interrupt number assignment for the MSS + UART blocks are defined as constants in the SmartFusion CMSIS-PAL You must ensure + that the SmartFusion CMSIS-PAL is either included in the software tool chain used + to build your project or is included in your project. + + + @section theory_op Theory of Operation + The MSS UART driver uses the SmartFusion "Cortex Microcontroler Software + Interface Standard - Peripheral Access Layer" (CMSIS-PAL) to access hadware + registers. You must ensure that the SmartFusion CMSIS-PAL is either included + in the software toolchain used to build your project or is included in your + project. The most up to date SmartFusion CMSIS-PAL files can be obtained using + the Actel Firmware Catalog. + + The MSS UART driver functions are logically grouped into three groups: + - Initialization functions + - Polled transmit and receive functions + - Interrupt driven transmit and receive functions + + The MSS UART driver is initialized through a call to the UART_init() function. + This function takes the UART's configuration as parameters. The UART_init() + function must be called before any other UART driver functions can be called. + The first parameter of the UART_init() function is a pointer to one of two + global data structures used to store state information for each UART driver. + A pointer to these data structures is also used as first parameter to any of + the driver functions to identify which UART will be used by the called + function. The name of these two data structures are g_mss_uart0 and + g_mss_uart1. Therefore any call to a MSS UART function should be of the form + UART_function_name( &g_mss_uart0, ... ) or UART_function_name( &g_mss_uart1, ... ). + The two SmartFusion MSS UARTs can also be configured to loop back to each + other using the MSS_set_loopback() function for debugging purposes. + + Polled operations where the processor constantly poll the UART registers state + in order to control data transmit or data receive is performed using functions: + - MSS_UART_polled_tx() + - MSS_UART_get_rx() + + Interrupt driven operations where the processor sets up transmit or receive + then returns to performing some other operation until an interrupts occurs + indicating that its attention is required is performed using functions: + - MSS_UART_irq_tx() + - MSS_UART_tx_complete() + - MSS_UART_set_rx_handler() + - MSS_UART_get_rx() + Interrupt driven transmit is initiated by a call to MSS_UART_irq_tx() specifying + the block of data to transmit. The processor can then perform some other + operation and later inquire whether transmit has completed by calling the + MSS_UART_tx_complete() function. + Interrupt driven receive is performed by first registering a receive handler + function that will be called by the driver whenever receive data is available. + This receive handler function in turns calls the MSS_UART_get_rx() function to + actually read the received data. + + *//*=========================================================================*/ +#ifndef __MSS_UART_H_ +#define __MSS_UART_H_ 1 + +#include "../../CMSIS/a2fxxxm3.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************************************************************//** + Baud rates. + The following definitions are used to specify standard baud rates as a + parameter to the MSS_UART_init() function. + */ +#define MSS_UART_110_BAUD 110 +#define MSS_UART_300_BAUD 300 +#define MSS_UART_1200_BAUD 1200 +#define MSS_UART_2400_BAUD 2400 +#define MSS_UART_4800_BAUD 4800 +#define MSS_UART_9600_BAUD 9600 +#define MSS_UART_19200_BAUD 19200 +#define MSS_UART_38400_BAUD 38400 +#define MSS_UART_57600_BAUD 57600 +#define MSS_UART_115200_BAUD 115200 +#define MSS_UART_230400_BAUD 230400 +#define MSS_UART_460800_BAUD 460800 +#define MSS_UART_921600_BAUD 921600 + +/***************************************************************************//** + Data bits length values. + + The following defines are used to build the value of the MSS_UART_init() + function line_config parameter. + */ +#define MSS_UART_DATA_5_BITS 0x00 +#define MSS_UART_DATA_6_BITS 0x01 +#define MSS_UART_DATA_7_BITS 0x02 +#define MSS_UART_DATA_8_BITS 0x03 + +/***************************************************************************//** + Parity values + The following defines are used to build the value of the MSS_UART_init() + function line_config parameter. + */ +#define MSS_UART_NO_PARITY 0x00 +#define MSS_UART_ODD_PARITY 0x08 +#define MSS_UART_EVEN_PARITY 0x18 +#define MSS_UART_STICK_PARITY_0 0x38 +#define MSS_UART_STICK_PARITY_1 0x28 + +/***************************************************************************//** + Stop bit values + The following defines are used to build the value of the MSS_UART_init() + function line_config parameter. + */ +#define MSS_UART_ONE_STOP_BIT 0x00 +#define MSS_UART_ONEHALF_STOP_BIT 0x04 +#define MSS_UART_TWO_STOP_BITS 0x04 + +/***************************************************************************//** + FIFO trigger sizes + This enumeration specifies the number of bytes that must be received before a + receive interrupt is generated. This enumeration provides the allowed values for + the MSS_UART_set_rx_handler() function trigger_level parameter. + */ +typedef enum __mss_uart_rx_trig_level_t { + MSS_UART_FIFO_SINGLE_BYTE = 0x00, + MSS_UART_FIFO_FOUR_BYTES = 0x40, + MSS_UART_FIFO_EIGHT_BYTES = 0x80, + MSS_UART_FIFO_FOURTEEN_BYTES = 0xC0 +} mss_uart_rx_trig_level_t; + +/***************************************************************************//** + Loopback. + This enumeration is used as parameter to function MSS_UART_set_loopback(). It + specifies the loopback configuration of the UARTs. Using MSS_UART_LOOPBACK_ON + as parameter to function MSS_UART_set_loopback() will set up the UART to locally + loopback its Tx and Rx lines. + */ +typedef enum __mss_uart_loopback_t { + MSS_UART_LOOPBACK_OFF = 0, + MSS_UART_LOOPBACK_ON = 1 +} mss_uart_loopback_t; + +/***************************************************************************//** + Receive handler prototype. + This typedef specifies the prototype of functions that can be registered with + this driver as receive handler functions. + */ +typedef void (*mss_uart_rx_handler_t)(void); + +/***************************************************************************//** + mss_uart_instance_t. + + There is one instance of this structure for each instance of the Microcontroller + Subsystem's UARTs. Instances of this structure are used to identify a specific + UART. A pointer to an instance of the mss_uart_instance_t structure is passed + as the first parameter to MSS UART driver functions to identify which UART + should perform the requested operation. + */ +typedef struct { + /* CMSIS related defines identifying the UART hardware. */ + UART_TypeDef * hw_reg; /*!< Pointer to UART registers. */ + UART_BitBand_TypeDef * hw_reg_bit; /*!< Pointer to UART registers bit band area. */ + IRQn_Type irqn; /*!< UART's Cortex-M3 NVIC interrupt number. */ + + /* transmit related info (used with interrupt driven trnasmit): */ + const uint8_t * tx_buffer; /*!< Pointer to transmit buffer. */ + uint32_t tx_buff_size; /*!< Transmit buffer size. */ + uint32_t tx_idx; /*!< Index within trnamit buffer of next byte to transmit.*/ + + /* receive interrupt handler:*/ + mss_uart_rx_handler_t rx_handler; /*!< Pointer to user registered received handler. */ +} mss_uart_instance_t; + +/***************************************************************************//** + This instance of mss_uart_instance_t holds all data related to the operations + performed by UART0. A pointer to g_mss_uart0 is passed as the first parameter + to MSS UART driver functions to indicate that UART0 should perform the requested + operation. + */ +extern mss_uart_instance_t g_mss_uart0; + +/***************************************************************************//** + This instance of mss_uart_instance_t holds all data related to the operations + performed by UART1. A pointer to g_mss_uart1 is passed as the first parameter + to MSS UART driver functions to indicate that UART1 should perform the requested + operation. + */ +extern mss_uart_instance_t g_mss_uart1; + +/***************************************************************************//** + The MSS_UART_init() function initializes and configures one of the SmartFusion + MSS UARTs with the configuration passed as a parameter. The configuration + parameters are the baud_rate which is used to generate the baud value and the + line_config which is used to specify the line configuration (bit length, stop + bits and parity). + + Example: + @code + #include "mss_uart.h" + + int main(void) + { + MSS_UART_init + ( + &g_mss_uart0, + MSS_UART_57600_BAUD, + MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT + ); + return(0); + } + @endcode + + @param this_uart + The this_uart parameter is a pointer to an mss_uart_instance_t structure + identifying the MSS UART hardware block to be initialized. There are two + such data structures, g_mss_uart0 and g_mss_uart1, associated with MSS UART0 + and MSS UART1 respectively. This parameter must point to either the + g_mss_uart0 or g_mss_uart1 global data structure defined within the UART + driver. + + + @param baud_rate + The baud_rate parameter specifies the baud rate. It can be specified for + common baud rates' using the following defines: + - MSS_UART_110_BAUD + - MSS_UART_300_BAUD + - MSS_UART_1200_BAUD + - MSS_UART_2400_BAUD + - MSS_UART_4800_BAUD + - MSS_UART_9600_BAUD + - MSS_UART_19200_BAUD + - MSS_UART_38400_BAUD + - MSS_UART_57600_BAUD + - MSS_UART_115200_BAUD + - MSS_UART_230400_BAUD + - MSS_UART_460800_BAUD + - MSS_UART_921600_BAUD + Alternatively, any non standard baud rate can be specified by simply passing + the actual required baud rate as value for this parameter. + + @param line_config + The line_config parameter is the line configuration specifying the bit length, + number of stop bits and parity settings. This is a logical OR of one of the + following to specify the transmit/receive data bit length: + - MSS_UART_DATA_5_BITS + - MSS_UART_DATA_6_BITS, + - MSS_UART_DATA_7_BITS + - MSS_UART_DATA_8_BITS + with one of the following to specify the parity setting: + - MSS_UART_NO_PARITY + - MSS_UART_EVEN_PARITY + - MSS_UART_ODD_PARITY + - MSS_UART_STICK_PARITY_0 + - MSS_UART_STICK_PARITY_1 + with one of the following to specify the number of stop bits: + - MSS_UART_ONE_STOP_BIT + - MSS_UART_ONEHALF_STOP_BIT + - MSS_UART_TWO_STOP_BITS + + @return + This function does not return a value. + */ +void +MSS_UART_init +( + mss_uart_instance_t* this_uart, + uint32_t baud_rate, + uint8_t line_config +); + +/***************************************************************************//** + The function MSS_UART_polled_tx() is used to transmit data. It transfers the + contents of the transmitter data buffer, passed as a function parameter, into + the UART's hardware transmitter FIFO. It returns when the full content of the + transmit data buffer has been transferred to the UART's transmit FIFO. + + @param this_uart + The this_uart parameter is a pointer to an mss_uart_instance_t structure + identifying the MSS UART hardware block that will perform the requested + function. There are two such data structures, g_mss_uart0 and g_mss_uart1, + associated with MSS UART0 and MSS UART1. This parameter must point to either + the g_mss_uart0 or g_mss_uart1 global data structure defined within the UART + driver. + + @param pbuff + The pbuff parameter is a pointer to a buffer containing the data to be + transmitted. + + @param tx_size + The tx_size parameter specifies the size, in bytes, of the data to be + transmitted. + + @return This function does not return a value. + */ +void +MSS_UART_polled_tx +( + mss_uart_instance_t * this_uart, + const uint8_t * pbuff, + uint32_t tx_size +); + +/***************************************************************************//** + The function MSS_UART_polled_tx_string() is used to transmit a zero-terminated + string. It transfers the text found starting at the address pointed to by + p_sz_string into the UART's hardware transmitter FIFO. It returns when the + complete string has been transferred to the UART's transmit FIFO. + + @param this_uart + The this_uart parameter is a pointer to an mss_uart_instance_t structure + identifying the MSS UART hardware block that will perform the requested + function. There are two such data structures, g_mss_uart0 and g_mss_uart1, + associated with MSS UART0 and MSS UART1. This parameter must point to either + the g_mss_uart0 or g_mss_uart1 global data structure defined within the UART + driver. + + @param p_sz_string + The p_sz_string parameter is a pointer to a buffer containing the + zero-terminated string to be transmitted. + + @return This function does not return a value. + */ +void +MSS_UART_polled_tx_string +( + mss_uart_instance_t * this_uart, + const uint8_t * p_sz_string +); + + +/***************************************************************************//** + The function MSS_UART_irq_tx() is used to initiate interrupt driven transmit. It + returns immediately after making a note of the transmit buffer location and + enabling transmit interrupts both at the UART and Cortex-M3 NVIC level. + This function takes a pointer to a memory buffer containing the data to + transmit as parameter. The memory buffer specified through this pointer + should remain allocated and contain the data to transmit until the transmit + completion has been detected through calls to function MSS_UART_tx_complete(). + NOTE: The MSS_UART_irq_tx() function also enables the Transmitter Holding + Register Empty (THRE) interrupt and the UART instance interrupt in the + Cortex-M3 NVIC as part of its implementation. + + Example: + @code + #include "mss_uart.h" + + int main(void) + { + uint8_t tx_buff[10] = "abcdefghi"; + MSS_UART_init( &g_mss_uart0, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT ); + MSS_UART_irq_tx( &g_mss_uart0, tx_buff, sizeof(tx_buff)); + while ( 0 == MSS_UART_tx_complete( &g_mss_uart0 ) ) + { + ; + } + return(0); + } + @endcode + + @param this_uart + The this_uart parameter is a pointer to an mss_uart_instance_t structure + identifying the MSS UART hardware block that will perform the requested + function. There are two such data structures, g_mss_uart0 and g_mss_uart1, + associated with MSS UART0 and MSS UART1. This parameter must point to either + the g_mss_uart0 or g_mss_uart1 global data structure defined within the UART + driver. + + @param pbuff + The pbuff parameter is a pointer to a buffer containing the data to be + transmitted. + + @param tx_size + The tx_size parameter specifies the size, in bytes, of the data to be + transmitted. + + @return + This function does not return a value. + */ +void +MSS_UART_irq_tx +( + mss_uart_instance_t * this_uart, + const uint8_t * pbuff, + uint32_t tx_size +); + +/***************************************************************************//** + The MSS_UART_tx_complete() function is used to find out if interrupt driven + transmit previously initiated through a call to MSS_UART_irq_tx() is complete. + This is typically used to find out when it is safe to reuse or release the + memory buffer holding transmit data. + + @param this_uart + The this_uart parameter is a pointer to an mss_uart_instance_t structure + identifying the MSS UART hardware block that will perform the requested + function. There are two such data structures, g_mss_uart0 and g_mss_uart1, + associated with MSS UART0 and MSS UART1. This parameter must point to either + the g_mss_uart0 or g_mss_uart1 global data structure defined within the UART + driver. + + @return + This function return a non-zero value if transmit has completed, otherwise + it returns zero. + + Example: + See the MSS_UART_irq_tx() function for an example that uses the + MSS_UART_tx_complete() function. + */ +int8_t +MSS_UART_tx_complete +( + mss_uart_instance_t * this_uart +); + +/***************************************************************************//** + The MSS_UART_get_rx() function is used to read the content of a UART's receive + FIFO. It can be used in polled mode where it is called at regular interval + to find out if any data has been received or in interrupt driven mode where + it is called as part of a receive handler called by the driver as a result of + data being received. This function is non-blocking and will return 0 + immediately if no data has been received. + NOTE: In interrupt driven mode you should call the MSS_UART_get_rx() function + as part of the receive handler function that you register with the MSS UART + driver through a call to MSS_UART_set_rx_handler(). + + @param this_uart + The this_uart parameter is a pointer to an mss_uart_instance_t structure + identifying the MSS UART hardware block that will perform the requested + function. There are two such data structures, g_mss_uart0 and g_mss_uart1, + associated with MSS UART0 and MSS UART1. This parameter must point to either + the g_mss_uart0 or g_mss_uart1 global data structure defined within the UART + driver. + + @param rx_buff + The rx_buff parameter is a pointer to a buffer where the received data will + be copied. + + @param buff_size + The buff_size parameter specifies the size of the receive buffer in bytes. + + @return + This function return the number of bytes that were copied into the rx_buff + buffer. It returns 0 if no data has been received. + + Polled mode example: + @code + int main( void ) + { + uint8_t rx_buff[RX_BUFF_SIZE]; + uint32_t rx_idx = 0; + + MSS_UART_init( &g_mss_uart0, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT ); + + while( 1 ) + { + rx_size = MSS_UART_get_rx( &g_mss_uart0, rx_buff, sizeof(rx_buff) ); + if (rx_size > 0) + { + process_rx_data( rx_buff, rx_size ); + } + task_a(); + task_b(); + } + return 0; + } + @endcode + + Interrupt driven example: + @code + int main( void ) + { + MSS_UART_init( &g_mss_uart1, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT ); + MSS_UART_set_rx_handler( &g_mss_uart1, uart1_rx_handler, MSS_UART_FIFO_SINGLE_BYTE ); + + while( 1 ) + { + task_a(); + task_b(); + } + return 0; + } + + void uart1_rx_handler( void ) + { + uint8_t rx_buff[RX_BUFF_SIZE]; + uint32_t rx_idx = 0; + rx_size = MSS_UART_get_rx( &g_mss_uart1, rx_buff, sizeof(rx_buff) ); + process_rx_data( rx_buff, rx_size ); + } + @endcode + */ +size_t +MSS_UART_get_rx +( + mss_uart_instance_t * this_uart, + uint8_t * rx_buff, + size_t buff_size +); + +/***************************************************************************//** + The MSS_UART_set_rx_handler() function is used to register a receive handler + function which will be called by the driver when a UART Received Data Available + (RDA) interrupt occurs. You must create and register the handler function to + suit your application. The MSS_UART_set_rx_handler() function also enables the UART + Received Data Available interrupt and the UART instance interrupt in the + Cortex-M3 NVIC as part of its implementation. + + @param this_uart + The this_uart parameter is a pointer to an mss_uart_instance_t structure + identifying the MSS UART hardware block that will perform the requested + function. There are two such data structures, g_mss_uart0 and g_mss_uart1, + associated with MSS UART0 and MSS UART1. This parameter must point to either + the g_mss_uart0 or g_mss_uart1 global data structure defined within the UART + driver. + + @param handler + The handler parameter is a pointer to a receive handler function provided + by your application which will be called as a result of a UART Received + Data Available interrupt. + + @param trigger_level + The trigger_level parameter is the receive FIFO trigger level. This specifies + the number of bytes that must be received before the UART triggers a Received + Data Available interrupt. + + @return + This function does not return a value. + + Example: + @code + #include "mss_uart.h" + + #define RX_BUFF_SIZE 64 + + uint8_t g_rx_buff[RX_BUFF_SIZE]; + + void uart0_rx_handler( void ) + { + MSS_UART_get_rx( &g_mss_uart, &g_rx_buff[g_rx_idx], sizeof(g_rx_buff) ); + } + + int main(void) + { + MSS_UART_init( &g_mss_uart0, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT ); + MSS_UART_set_rx_handler( &g_mss_uart0, uart0_rx_handler, MSS_UART_FIFO_SINGLE_BYTE ); + + while ( 1 ) + { + ; + } + return(0); + } + @endcode + */ +void +MSS_UART_set_rx_handler +( + mss_uart_instance_t * this_uart, + mss_uart_rx_handler_t handler, + mss_uart_rx_trig_level_t trigger_level +); + +/***************************************************************************//** + The MSS_UART_set_loopback() function is used to locally loopback the Tx and Rx + lines of a UART. + This is not to be confused with the loopback of UART0 to UART1 which can be + achieved through the microcontroller subsystem's system registers + + @param this_uart + The this_uart parameter is a pointer to an mss_uart_instance_t structure + identifying the MSS UART hardware block that will perform the requested + function. There are two such data structures, g_mss_uart0 and g_mss_uart1, + associated with MSS UART0 and MSS UART1. This parameter must point to either + the g_mss_uart0 or g_mss_uart1 global data structure defined within the UART + driver. + + @param loopback + The loopback parameter indicates whether or not the UART's transmit and receive lines + should be looped back. Allowed values are: + - MSS_UART_LOOPBACK_ON + - MSS_UART_LOOPBACK_OFF + @return + This function does not return a value. + */ +void +MSS_UART_set_loopback +( + mss_uart_instance_t * this_uart, + mss_uart_loopback_t loopback +); + +#ifdef __cplusplus +} +#endif + +#endif /* __MSS_UART_H_ */ diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_watchdog/mss_watchdog.h b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_watchdog/mss_watchdog.h new file mode 100644 index 000000000..337a91bb1 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_watchdog/mss_watchdog.h @@ -0,0 +1,427 @@ +/******************************************************************************* + * (c) Copyright 2009 Actel Corporation. All rights reserved. + * + * SmartFusion Microcontroller Subsystem (MSS) Watchdog bare metal software + * driver. + * + * SVN $Revision: 1888 $ + * SVN $Date: 2009-12-18 10:58:42 +0000 (Fri, 18 Dec 2009) $ + */ +/*=========================================================================*//** + @section intro_sec Introduction + The SmartFusion microcontroller subsystem (MSS) includes a watchdog timer used + to detect system lockups. + This driver provides a set of functions for controlling the MSS watchdog as + part of a bare metal system where no operating system is available. These + drivers can be adapted for use as part of an operating system but the + implementation of the adaptation layer between this driver and the operating + system's driver model is outside the scope of this driver. + + @section hw_dependencies Hardware Flow Dependencies + The configuration of all features of the MSS watchdog is covered by this + driver. There are no dependencies on the hardware flow for configuring the + SmartFusion MSS watchdog timer. + + @section theory_op Theory of Operation + The watchdog driver uses the SmartFusion "Cortex Microcontroler Software + Interface Standard - Peripheral Access Layer" (CMSIS-PAL) to access hadware + registers. You must ensure that the SmartFusion CMSIS-PAL is either included + in the software toolchain used to build your project or is included in your + project. The most up-to-date SmartFusion CMSIS-PAL files can be obtained using + the Actel Firmware Catalog. + + The watchdog driver functions are grouped into the following categories: + - Initialization and cnfiguration + - Reading the watchdog timer current value and status + - Refreshing the watchdog timer value + - Time-out and wake-up interrupts control + + The watchdog driver is initialized and configured through a call to the + MSS_WD_init() function. The parameters passed to MSS_WD_init() function + specify the watchdog timer configuration. The configuration parameters include + the value that will be reloaded into the watchdog timer down counter every + time the watchdog is refreshed. Also included as part of the configuration + parameters is the optional allowed refresh window. The allowed refresh window + specifies the maximum allowed current value of the watchdog timer at the time + of the watchdog is relaoded. Attempting to reload the watchdog timer when its + value is larger than the allowed refresh window will cause a reset or + interrupt depending on the watchdog configuration. The allowed refresh window + can be disabled by specifying an allowed refesh window equal or higher than + the watchdog reload value. + The MSS_WD_init() function must be called before any other watchdog driver + functions can be called with the exception of the MSS_WD_disable() function. + + The watchdog timer can be disabled using the MSS_WD_disable() function. Once + disabled, the watchdog timer can only be reenabled by a power-on reset. + + The watchdog timer current value can be read using the MSS_WD_current_value() + function. The watchdog status can be read using the MSS_WD_status() function. + These functions are typically required when using the watchdog configured with + an allowed refresh window to check if a watchdog reload is currently allowed. + + The watchdog timer value is reloaded using the MSS_WD_reload() function. The + value reloaded into the watchdog timer down counter is the value specified as + parameter to the MSS_WD_init() function. + + The watchdog timer can generate interrupts instead of resetting the system + when its down-counter timer expires. These time-out interrupts are controlled + using the following functions: + - MSS_WD_enable_timeout_irq + - MSS_WD_disable_timeout_irq + - MSS_WD_clear_timeout_irq + + The watchdog timer is external to the Cortex-M3 processor core and operates + even when the Cortex-M3 is in sleep mode. A wakeup interrupt can be generated + by the watchdog timer to wakeup the Cortext-M3 when the watchdog timer value + reaches the allowed refresh window while the Cortex-M3 is in sleep mode. The + watchdog driver provides the following functions to control wakeup interrupts: + - MSS_WD_enable_wakeup_irq + - MSS_WD_disable_wakeup_irq + - MSS_WD_clear_wakeup_irq + + *//*=========================================================================*/ + +#ifndef MSS_WATCHDOG_H_ +#define MSS_WATCHDOG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../../CMSIS/a2fxxxm3.h" + +/***************************************************************************//** + * The MSS_WDOG_RESET_ON_TIMEOUT_MODE macro is one of the possible values for the + * mode parameter of the WD_init() function. It is used to specify that a reset + * should occur when the watchdog down counter times out. + */ +#define MSS_WDOG_RESET_ON_TIMEOUT_MODE (uint32_t)0x00000000U + +/***************************************************************************//** + * The MSS_WDOG_INTERRUPT_ON_TIMEOUT_MODE macro is one of the possible values for + * the mode parameter of function the WD_init() function. It is used to specify + * that a time out interrupt should occur when the watchdog down counter expires. + */ +#define MSS_WDOG_INTERRUPT_ON_TIMEOUT_MODE (uint32_t)0x00000004U + +/***************************************************************************//** + * The MSS_WDOG_NO_WINDOW macro can be used as the value for the reload_window + * parameter of the WD_init() function. It is used to specify that no forbidden + * window will exist for the reload of the watchdog down counter. + */ +#define MSS_WDOG_NO_WINDOW (uint32_t)0xFFFFFFFFU + +/***************************************************************************//** + * The MSS_WDOG_CTRL_MODE_BIT_MASK macro is a bit mask specifying the bit used to + * set the watchdog's operating mode within the wathcdog's WDOGCONTROL register. + */ +#define MSS_WDOG_CTRL_MODE_BIT_MASK (uint32_t)0x00000004U + +/***************************************************************************//** + * The MSS_WDOG_TIMEOUT_IRQ_ENABLE_BIT_MASK macro is a bit mask specifying the bit + * used to enable the time out interrupt within the watchdog's WDOGCONTROL + * register. + */ +#define MSS_WDOG_TIMEOUT_IRQ_ENABLE_BIT_MASK (uint32_t)0x00000001U + +/***************************************************************************//** + The MSS_WDOG_WAKEUP_IRQ_ENABLE_BIT_MASK macro is a bit mask specifying the bit + used to enable the wake up interrupt within the watchdog's WDOGCONTROL + register. + */ +#define MSS_WDOG_WAKEUP_IRQ_ENABLE_BIT_MASK (uint32_t)0x00000002U + +/***************************************************************************//** + The MSS_WDOG_TIMEOUT_IRQ_CLEAR_BIT_MASK macro is a bit mask specifying the bit + used to clear the time out interrupt within the watchdog's WDOGRIS register. + */ +#define MSS_WDOG_TIMEOUT_IRQ_CLEAR_BIT_MASK (uint32_t)0x00000001U + +/***************************************************************************//** + The MSS_WDOG_WAKEUP_IRQ_CLEAR_BIT_MASK macro is a bit mask specifying the bit + used to clear the wake up interrupt within the watchdog's WDOGRIS register. + */ +#define MSS_WDOG_WAKEUP_IRQ_CLEAR_BIT_MASK (uint32_t)0x00000002U + +/***************************************************************************//** + The MSS_WDOG_REFRESH_KEY macro holds the magic value which will cause a reload + of the watchdog's down counter when written to the watchdog's WDOGREFRESH + register. + */ +#define MSS_WDOG_REFRESH_KEY (uint32_t)0xAC15DE42U + +/***************************************************************************//** + The MSS_WDOG_DISABLE_KEY macro holds the magic value which will disable the + watchdog if written to the watchdog's WDOGENABLE register. + */ +#define MSS_WDOG_DISABLE_KEY (uint32_t)0x4C6E55FAU + +/***************************************************************************//** + The MSS_WD_init() function initializes and configures the watchdog timer. + + @param load_value + The load_value parameter specifies the value that will be loaded into the + watchdog's down counter when the reload command is issued through a call to + MSS_WD_reload(). + + @param reload_window + The reload_window parameter specifies the time window during which a reload + of the watchdog counter is allowed. A reload of the watchdog counter should + only be performed when the watchdog counter value is below the value of the + reload_window. Reloading the watchdog down counter value before it has + reached the reload_window will result in an interrupt or reset depending on + the watchdog's mode. + The reload window can be disabled by using WDOG_NO_WINDOW for this parameter. + + @param mode + The mode parameter specifies the watchdog's operating mode. It can be either + MSS_WDOG_RESET_ON_TIMEOUT_MODE or MSS_WDOG_INTERRUPT_ON_TIMEOUT_MODE. + MSS_WDOG_RESET_ON_TIMEOUT_MODE: a reset will occur if the watchdog timer + expires. + MSS_WDOG_INTERRUPT_ON_TIMEOUT_MODE: an NMI interrupt will occur if the + watchdog timer expires. + + @return + This function does not return a value. + */ +static __INLINE void MSS_WD_init +( + uint32_t load_value, + uint32_t reload_window, + uint32_t mode +) +{ + /* Disable interrupts. */ + WATCHDOG->WDOGCONTROL &= ~(MSS_WDOG_TIMEOUT_IRQ_ENABLE_BIT_MASK | MSS_WDOG_WAKEUP_IRQ_CLEAR_BIT_MASK); + + /* Clear any existing interrupts. */ + WATCHDOG->WDOGRIS = MSS_WDOG_TIMEOUT_IRQ_CLEAR_BIT_MASK | MSS_WDOG_WAKEUP_IRQ_CLEAR_BIT_MASK; + + /* Configure watchdog with new configuration passed as parameter. */ + WATCHDOG->WDOGMVRP = MSS_WDOG_NO_WINDOW; + WATCHDOG->WDOGLOAD = load_value; + WATCHDOG->WDOGCONTROL = (WATCHDOG->WDOGCONTROL & ~MSS_WDOG_CTRL_MODE_BIT_MASK) | (mode & MSS_WDOG_CTRL_MODE_BIT_MASK); + + /* Reload watchdog with new load value. */ + WATCHDOG->WDOGREFRESH = MSS_WDOG_REFRESH_KEY; + + /* Set allowed window. */ + WATCHDOG->WDOGMVRP = reload_window; +} + +/***************************************************************************//** + The MSS_WD_reload() function causes the watchdog to reload its down counter timer + with the load value configured through the call to WD_init(). This function + must be called regularly to avoid a system reset. + + @return + This function does not return a value. + */ +static __INLINE void MSS_WD_reload( void ) +{ + WATCHDOG->WDOGREFRESH = MSS_WDOG_REFRESH_KEY; +} + +/***************************************************************************//** + The MSS_WD_disable() function disables the watchdog. + Please note that the watchdog can only be reenabled as a result of a power-on + reset. + + @return + This function does not return a value. + */ +static __INLINE void MSS_WD_disable( void ) +{ + WATCHDOG->WDOGENABLE = MSS_WDOG_DISABLE_KEY; +} + +/***************************************************************************//** + The MSS_WD_current_value() function returns the current value of the watchdog's + down counter. + + @return + This function returns the current value of the watchdog down counter. + */ +static __INLINE uint32_t MSS_WD_current_value( void ) +{ + return WATCHDOG->WDOGVALUE; +} + +/***************************************************************************//** + The MSS_WD_status() function returns the status of the watchdog. + + @return + The MSS_WD_status() function returns the status of the watchdog. A value of + 0 indicates that watchdog counter has reached the forbidden window and that + a reload should not be done. A value of 1 indicates that the watchdog counter + is within the permitted window and that a reload is allowed. + */ +static __INLINE uint32_t MSS_WD_status( void ) +{ + return WATCHDOG->WDOGSTATUS; +} + +/***************************************************************************//** + The MSS_WD_enable_timeout_irq() function enables the watchdog’s time out + interrupt which is connected to the Cortex-M3 NMI interrupt. + The NMI_Handler() function will be called when a watchdog time out occurs. You + must provide the implementation of the NMI_Handler() function to suit your + application. + + @return + This function does not return a value. + + Example: + @code + #include "mss_watchdog.h" + int main( void ) + { + MSS_WD_init( 0x10000000, MSS_WDOG_NO_WINDOW, MSS_WDOG_INTERRUPT_ON_TIMEOUT_MODE ); + MSS_WD_enable_timeout_irq(); + for (;;) + { + main_task(); + } + } + + void NMI_Handler( void ) + { + process_timeout(); + MSS_WD_clear_timeout_irq(); + } + @endcode + */ +static __INLINE void MSS_WD_enable_timeout_irq( void ) +{ + WATCHDOG->WDOGCONTROL |= MSS_WDOG_TIMEOUT_IRQ_ENABLE_BIT_MASK; +} + +/***************************************************************************//** + The WD_disable_timeout_irq() function disables the generation of the NMI + interrupt when the watchdog times out. + + @return + This function does not return a value. + */ +static __INLINE void MSS_WD_disable_timeout_irq( void ) +{ + WATCHDOG->WDOGCONTROL &= ~MSS_WDOG_TIMEOUT_IRQ_ENABLE_BIT_MASK; +} + +/***************************************************************************//** + The MSS_WD_enable_wakeup_irq() function enables the SmartFusion wakeup + interrupt. The WdogWakeup_IRQHandler() function will be called when a wake up + interrupt occurs. You must provide the implementation of the WdogWakeup_IRQHandler() + function to suit your application. + + @return + This function does not return a value. + + Example: + @code + #include "mss_watchdog.h" + int main( void ) + { + MSS_WD_init( 0x10000000, MSS_WDOG_NO_WINDOW, MSS_WDOG_INTERRUPT_ON_TIMEOUT_MODE ); + MSS_WD_enable_wakeup_irq(); + for (;;) + { + main_task(); + cortex_sleep(); + } + } + + void WdogWakeup_IRQHandler( void ) + { + process_wakeup(); + MSS_WD_clear_wakeup_irq(); + } + @endcode + */ +static __INLINE void MSS_WD_enable_wakeup_irq( void ) +{ + WATCHDOG->WDOGCONTROL |= MSS_WDOG_WAKEUP_IRQ_ENABLE_BIT_MASK; + NVIC_EnableIRQ( WdogWakeup_IRQn ); +} + +/***************************************************************************//** + The MSS_WD_disable_wakeup_irq() function disables the SmartFusion wakeup + interrupt. + + @return + This function does not return a value. + */ +static __INLINE void MSS_WD_disable_wakeup_irq( void ) +{ + WATCHDOG->WDOGCONTROL &= ~MSS_WDOG_WAKEUP_IRQ_ENABLE_BIT_MASK; +} + +/***************************************************************************//** + The MSS_WD_clear_timeout_irq() function clears the watchdog’s time out + interrupt which is connected to the Cortex-M3 NMI interrupt. + Calling MSS_WD_clear_timeout_irq() results in clearing the Cortex-M3 NMI interrupt. + Note: The MSS_WD_clear_timeout_irq() function must be called as part of the + timeout interrupt service routine (ISR) in order to prevent the same interrupt + event retriggering a call to the wakeup ISR. + + @return + The example below demonstrates the use of the MSS_WD_clear_timeout_irq() + function as part of the NMI interrupt service routine. + + Example: + @code + void NMI_Handler( void ) + { + process_timeout(); + MSS_WD_clear_timeout_irq(); + } + @endcode + */ +static __INLINE void MSS_WD_clear_timeout_irq( void ) +{ + WATCHDOG->WDOGRIS = MSS_WDOG_TIMEOUT_IRQ_CLEAR_BIT_MASK; + /* + * Perform a second write to ensure that the first write completed before + * returning from this function. This is to account for posted writes across + * the AHB matrix. The second write ensures that the first write has + * completed and that the interrupt line has been de-asserted by the time + * the function returns. Omitting the second write may result in a delay + * in the de-assertion of the interrupt line going to the Cortex-M3 and a + * retriggering of the interrupt. + */ + WATCHDOG->WDOGRIS = MSS_WDOG_TIMEOUT_IRQ_CLEAR_BIT_MASK; +} + +/***************************************************************************//** + The MSS_WD_clear_wakeup_irq() function clears the wakeup interrupt. + Note: The MSS_WD_clear_wakeup_irq() function must be called as part of the + wakeup interrupt service routine (ISR) in order to prevent the same interrupt + event retriggering a call to the wakeup ISR. This function also clears the + interrupt in the Cortex-M3 interrupt controller through a call to + NVIC_ClearPendingIRQ(). + + @return + This function does not return a value. + + Example: + The example below demonstrates the use of the MSS_WD_clear_wakeup_irq() function + as part of the wakeup interrupt service routine. + @code + void WdogWakeup_IRQHandler( void ) + { + do_interrupt_processing(); + + MSS_WD_clear_wakeup_irq(); + } + @endcode +*/ +static __INLINE void MSS_WD_clear_wakeup_irq( void ) +{ + WATCHDOG->WDOGRIS = MSS_WDOG_WAKEUP_IRQ_CLEAR_BIT_MASK; + NVIC_ClearPendingIRQ( WdogWakeup_IRQn ); +} +#ifdef __cplusplus +} +#endif + +#endif /* MSS_WATCHDOG_H_ */ diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/ParTest.c b/Demo/CORTEX_A2F200_IAR_and_Keil/ParTest.c new file mode 100644 index 000000000..4689074a0 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/ParTest.c @@ -0,0 +1,179 @@ +/* + FreeRTOS V7.0.0 - Copyright (C) 2011 Real Time Engineers Ltd. + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and 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 modification 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. +*/ + +/*----------------------------------------------------------- + * Simple parallel port IO routines. + *-----------------------------------------------------------*/ + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Library includes. */ +#include "mss_gpio.h" + +#define partstMAX_LEDS 8 + +static volatile unsigned long ulGPIOState = 0UL; + +/*-----------------------------------------------------------*/ + +void vParTestInitialise( void ) +{ +long x; + + /* Initialise the GPIO */ + MSS_GPIO_init(); + + /* Set up GPIO for the LEDs. */ + for( x = 0; x < partstMAX_LEDS; x++ ) + { + MSS_GPIO_config( ( mss_gpio_id_t ) x , MSS_GPIO_OUTPUT_MODE ); + } + + /* All LEDs start off. */ + ulGPIOState = 0xffffffffUL; + MSS_GPIO_set_outputs( ulGPIOState ); +} +/*-----------------------------------------------------------*/ + +void vParTestSetLED( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE xValue ) +{ + if( uxLED < partstMAX_LEDS ) + { + /* A critical section is used as the LEDs are also accessed from an + interrupt. */ + taskENTER_CRITICAL(); + { + if( xValue == pdTRUE ) + { + ulGPIOState &= ~( 1UL << uxLED ); + } + else + { + ulGPIOState |= ( 1UL << uxLED ); + } + + MSS_GPIO_set_outputs( ulGPIOState ); + } + taskEXIT_CRITICAL(); + } +} +/*-----------------------------------------------------------*/ + +void vParTestSetLEDFromISR( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE xValue ) +{ +unsigned portBASE_TYPE uxInterruptFlags; + + uxInterruptFlags = portSET_INTERRUPT_MASK_FROM_ISR(); + { + if( uxLED < partstMAX_LEDS ) + { + if( xValue == pdTRUE ) + { + ulGPIOState &= ~( 1UL << uxLED ); + } + else + { + ulGPIOState |= ( 1UL << uxLED ); + } + + MSS_GPIO_set_outputs( ulGPIOState ); + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxInterruptFlags ); +} +/*-----------------------------------------------------------*/ + +void vParTestToggleLED( unsigned portBASE_TYPE uxLED ) +{ + if( uxLED < partstMAX_LEDS ) + { + /* A critical section is used as the LEDs are also accessed from an + interrupt. */ + taskENTER_CRITICAL(); + { + if( ( ulGPIOState & ( 1UL << uxLED ) ) != 0UL ) + { + ulGPIOState &= ~( 1UL << uxLED ); + } + else + { + ulGPIOState |= ( 1UL << uxLED ); + } + + MSS_GPIO_set_outputs( ulGPIOState ); + } + taskEXIT_CRITICAL(); + } +} +/*-----------------------------------------------------------*/ + +long lParTestGetLEDState( unsigned long ulLED ) +{ +long lReturn = pdFALSE; + + if( ulLED < partstMAX_LEDS ) + { + taskENTER_CRITICAL(); + { + if( ( ulGPIOState & ( 1UL << ulLED ) ) == 0UL ) + { + lReturn = pdTRUE; + } + } + } + + return lReturn; +} +/*-----------------------------------------------------------*/ diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-cgi.c b/Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-cgi.c new file mode 100644 index 000000000..432f957bb --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-cgi.c @@ -0,0 +1,277 @@ +/** + * \addtogroup httpd + * @{ + */ + +/** + * \file + * Web server script interface + * \author + * Adam Dunkels + * + */ + +/* + * Copyright (c) 2001-2006, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack. + * + * $Id: httpd-cgi.c,v 1.2 2006/06/11 21:46:37 adam Exp $ + * + */ +#include "net/uip.h" +#include "net/psock.h" +#include "apps/httpd/httpd.h" +#include "apps/httpd/httpd-cgi.h" +#include "apps/httpd/httpd-fs.h" + +#include +#include + +#include "FreeRTOS.h" +#include "task.h" + +HTTPD_CGI_CALL( file, "file-stats", file_stats ); +HTTPD_CGI_CALL( tcp, "tcp-connections", tcp_stats ); +HTTPD_CGI_CALL( net, "net-stats", net_stats ); +HTTPD_CGI_CALL( rtos, "rtos-stats", rtos_stats ); +HTTPD_CGI_CALL( run, "run-time", run_time ); +HTTPD_CGI_CALL( io, "led-io", led_io ); + +static const struct httpd_cgi_call *calls[] = { &file, &tcp, &net, &rtos, &run, &io, NULL }; + +/*---------------------------------------------------------------------------*/ +static PT_THREAD( nullfunction ( struct httpd_state *s, char *ptr ) ) +{ + PSOCK_BEGIN( &s->sout ); + ( void ) ptr; + ( void ) PT_YIELD_FLAG; + PSOCK_END( &s->sout ); +} + +/*---------------------------------------------------------------------------*/ +httpd_cgifunction httpd_cgi( char *name ) +{ + const struct httpd_cgi_call **f; + + /* Find the matching name in the table, return the function. */ + for( f = calls; *f != NULL; ++f ) + { + if( strncmp((*f)->name, name, strlen((*f)->name)) == 0 ) + { + return( *f )->function; + } + } + + return nullfunction; +} + +/*---------------------------------------------------------------------------*/ +static unsigned short generate_file_stats( void *arg ) +{ + char *f = ( char * ) arg; + return sprintf( ( char * ) uip_appdata, "%5u", httpd_fs_count(f) ); +} + +/*---------------------------------------------------------------------------*/ +static PT_THREAD( file_stats ( struct httpd_state *s, char *ptr ) ) +{ + PSOCK_BEGIN( &s->sout ); + + ( void ) PT_YIELD_FLAG; + + PSOCK_GENERATOR_SEND( &s->sout, generate_file_stats, strchr(ptr, ' ') + 1 ); + + PSOCK_END( &s->sout ); +} + +/*---------------------------------------------------------------------------*/ +static const char closed[] = /* "CLOSED",*/ { 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0 }; +static const char syn_rcvd[] = /* "SYN-RCVD",*/ { 0x53, 0x59, 0x4e, 0x2d, 0x52, 0x43, 0x56, 0x44, 0 }; +static const char syn_sent[] = /* "SYN-SENT",*/ { 0x53, 0x59, 0x4e, 0x2d, 0x53, 0x45, 0x4e, 0x54, 0 }; +static const char established[] = /* "ESTABLISHED",*/ { 0x45, 0x53, 0x54, 0x41, 0x42, 0x4c, 0x49, 0x53, 0x48, 0x45, 0x44, 0 }; +static const char fin_wait_1[] = /* "FIN-WAIT-1",*/ { 0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49, 0x54, 0x2d, 0x31, 0 }; +static const char fin_wait_2[] = /* "FIN-WAIT-2",*/ { 0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49, 0x54, 0x2d, 0x32, 0 }; +static const char closing[] = /* "CLOSING",*/ { 0x43, 0x4c, 0x4f, 0x53, 0x49, 0x4e, 0x47, 0 }; +static const char time_wait[] = /* "TIME-WAIT,"*/ { 0x54, 0x49, 0x4d, 0x45, 0x2d, 0x57, 0x41, 0x49, 0x54, 0 }; +static const char last_ack[] = /* "LAST-ACK"*/ { 0x4c, 0x41, 0x53, 0x54, 0x2d, 0x41, 0x43, 0x4b, 0 }; + +static const char *states[] = { closed, syn_rcvd, syn_sent, established, fin_wait_1, fin_wait_2, closing, time_wait, last_ack }; + +static unsigned short generate_tcp_stats( void *arg ) +{ + struct uip_conn *conn; + struct httpd_state *s = ( struct httpd_state * ) arg; + + conn = &uip_conns[s->count]; + return sprintf( ( char * ) uip_appdata, + "%d%u.%u.%u.%u:%u%s%u%u%c %c\r\n", htons(conn->lport), + htons(conn->ripaddr.u16[0]) >> 8, htons(conn->ripaddr.u16[0]) & 0xff, htons(conn->ripaddr.u16[1]) >> 8, + htons(conn->ripaddr.u16[1]) & 0xff, htons(conn->rport), states[conn->tcpstateflags & UIP_TS_MASK], conn->nrtx, conn->timer, + (uip_outstanding(conn)) ? '*' : ' ', (uip_stopped(conn)) ? '!' : ' ' ); +} + +/*---------------------------------------------------------------------------*/ +static PT_THREAD( tcp_stats ( struct httpd_state *s, char *ptr ) ) +{ + PSOCK_BEGIN( &s->sout ); + ( void ) ptr; + ( void ) PT_YIELD_FLAG; + for( s->count = 0; s->count < UIP_CONNS; ++s->count ) + { + if( (uip_conns[s->count].tcpstateflags & UIP_TS_MASK) != UIP_CLOSED ) + { + PSOCK_GENERATOR_SEND( &s->sout, generate_tcp_stats, s ); + } + } + + PSOCK_END( &s->sout ); +} + +/*---------------------------------------------------------------------------*/ +static unsigned short generate_net_stats( void *arg ) +{ + struct httpd_state *s = ( struct httpd_state * ) arg; + return sprintf( ( char * ) uip_appdata, "%5u\n", (( uip_stats_t * ) &uip_stat)[s->count] ); +} + +static PT_THREAD( net_stats ( struct httpd_state *s, char *ptr ) ) +{ + PSOCK_BEGIN( &s->sout ); + ( void ) ptr; + ( void ) PT_YIELD_FLAG; +#if UIP_STATISTICS + for( s->count = 0; s->count < sizeof(uip_stat) / sizeof(uip_stats_t); ++s->count ) + { + PSOCK_GENERATOR_SEND( &s->sout, generate_net_stats, s ); + } + +#endif /* UIP_STATISTICS */ + + PSOCK_END( &s->sout ); +} + +/*---------------------------------------------------------------------------*/ +extern void vTaskList( signed char *pcWriteBuffer ); +extern char *pcGetTaskStatusMessage( void ); +static char cCountBuf[128]; +long lRefreshCount = 0; +static unsigned short generate_rtos_stats( void *arg ) +{ + ( void ) arg; + lRefreshCount++; + sprintf( cCountBuf, "


Refresh count = %d


%s", ( int ) lRefreshCount, pcGetTaskStatusMessage() ); + vTaskList( uip_appdata ); + strcat( uip_appdata, cCountBuf ); + + return strlen( uip_appdata ); +} + +/*---------------------------------------------------------------------------*/ +static PT_THREAD( rtos_stats ( struct httpd_state *s, char *ptr ) ) +{ + PSOCK_BEGIN( &s->sout ); + ( void ) ptr; + ( void ) PT_YIELD_FLAG; + PSOCK_GENERATOR_SEND( &s->sout, generate_rtos_stats, NULL ); + PSOCK_END( &s->sout ); +} + +/*---------------------------------------------------------------------------*/ +char *pcStatus; +unsigned long ulString; + +static unsigned short generate_io_state( void *arg ) +{ + extern long lParTestGetLEDState( unsigned long ulLED ); + ( void ) arg; + + /* Are the dynamically setable LEDs currently on or off? */ + if( lParTestGetLEDState( 8 ) ) + { + pcStatus = "checked"; + } + else + { + pcStatus = ""; + } + + sprintf( uip_appdata, "LED

", pcStatus ); + + return strlen( uip_appdata ); +} + +/*---------------------------------------------------------------------------*/ +extern void vTaskGetRunTimeStats( signed char *pcWriteBuffer ); +extern unsigned short usMaxJitter; +static char cJitterBuffer[ 200 ]; +static unsigned short generate_runtime_stats( void *arg ) +{ + ( void ) arg; + lRefreshCount++; + sprintf( cCountBuf, "


Refresh count = %d", ( int ) lRefreshCount ); + + #ifdef INCLUDE_HIGH_FREQUENCY_TIMER_TEST + { + sprintf( cJitterBuffer, "


Max high frequency timer jitter = %d peripheral clock periods.


", ( int ) usMaxJitter ); + vTaskGetRunTimeStats( uip_appdata ); + strcat( uip_appdata, cJitterBuffer ); + } + #else + { + ( void ) cJitterBuffer; + strcpy( uip_appdata, "

Run time stats are only available in the debug_with_optimisation build configuration.

" ); + } + #endif + + strcat( uip_appdata, cCountBuf ); + + return strlen( uip_appdata ); +} + +/*---------------------------------------------------------------------------*/ +static PT_THREAD( run_time ( struct httpd_state *s, char *ptr ) ) +{ + PSOCK_BEGIN( &s->sout ); + ( void ) ptr; + ( void ) PT_YIELD_FLAG; + PSOCK_GENERATOR_SEND( &s->sout, generate_runtime_stats, NULL ); + PSOCK_END( &s->sout ); +} + +/*---------------------------------------------------------------------------*/ +static PT_THREAD( led_io ( struct httpd_state *s, char *ptr ) ) +{ + PSOCK_BEGIN( &s->sout ); + ( void ) ptr; + ( void ) PT_YIELD_FLAG; + PSOCK_GENERATOR_SEND( &s->sout, generate_io_state, NULL ); + PSOCK_END( &s->sout ); +} + +/** @} */ diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-fs/404.html b/Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-fs/404.html new file mode 100644 index 000000000..43e7f4cad --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-fs/404.html @@ -0,0 +1,8 @@ + + +

+

404 - file not found

+

Go here instead.

+
+ + \ No newline at end of file diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-fs/index.html b/Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-fs/index.html new file mode 100644 index 000000000..4937dc69a --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-fs/index.html @@ -0,0 +1,13 @@ + + + + FreeRTOS.org uIP WEB server demo + + + +Loading index.shtml. Click here if not automatically redirected. + + + + + diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-fs/index.shtml b/Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-fs/index.shtml new file mode 100644 index 000000000..882d085ce --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-fs/index.shtml @@ -0,0 +1,20 @@ + + + + FreeRTOS.org uIP WEB server demo + + + +Task Stats | Run Time Stats | TCP Stats | Connections | FreeRTOS Homepage | IO | 37K jpg +

+


+

+

Task statistics

+Page will refresh every 2 seconds.

+

Task          State  Priority  Stack	#
************************************************
+%! rtos-stats +
+
+ + + diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-fs/io.shtml b/Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-fs/io.shtml new file mode 100644 index 000000000..819e2d39b --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-fs/io.shtml @@ -0,0 +1,28 @@ + + + + FreeRTOS.org uIP WEB server demo + + + +Task Stats | Run Time Stats | TCP Stats | Connections | FreeRTOS Homepage | IO | 37K jpg +

+


+LED and LCD IO
+ +

+ +Use the check box to turn on or off LED 4, then click "Update IO". + + +

+

+%! led-io +

+ +

+

+ + + + diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-fs/logo.jpg b/Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-fs/logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..46d756892a1480937294d92a3b1e2fd53ddc46b6 GIT binary patch literal 32592 zcmbTec|4Ti_cuOBLN(bUVk%j(W=q6O5weG@VJc*qkbO5HON3AqG9mji*|UyaLb8q} zd-iR{GG@%;x%+;e<@%QhX*LALQ-shb6?PTI)9&|xRQ(F^6M+XAY z0Y9LVX^=XIfu8=~3ph>zFUB*BjHga9vM@27K694k>{(V8R@QUp*)Np9N<&&NqCi0usB8Txhxx@#bM zHaZ42x|2>21Q;hH-G3dR|9Q~S17keRbcUIQ6=+a%0Yp#7z(9YB;oqo%)*-;>pi^v& z>{n&(o#rrl%5=?xQ#LFq`;4GkMH`p#5bnC%GtY2lmW$jxmw1JQMMQ6i$t&Daysf0H zeqTdV>w&h8$swe*OW05w9boqGR5~Ca1jrkec@KQ+iJB z*S!3K!lL5Js_L5By6^Q3?H!$6-90~ge-4j~j*Vj{CZ`q_m;NrVtgfwZ;P>_q4hcs@ z((ymJ=s*nr5es<#k6{0oTx@_`^rucSoMQSX7ahGHa5Au+V!SGIn*E*;(^C(QYqDWy zIMtG}E83U^<&1G$&pd}%E?$>k5W@cx?Y|`Ze-kYH|CeO{Td@Bl*A(b110Aq<3~V46 zh-#7(D+>DWXYtW-WbFq>$+5rq>Bsl;vMepc3Iz_kgAIsP`4pw<2jA+Z#=046v*M#X z4HOlR%t?gei|})(?%!QS#O{UN{7($|S+C2QYlFm&psVTgMQ@sBcv;gCp?zbtjLb@O zfUl*4t1h-Ou z-=IDgZb?Rl39uqbuQj0`SZRYamXz|;+%-fy`t?9bV?&WtZ_Tkau7XGJSL1MH>{j&& zC_Fd`)(yU7{lJEz5o&SR`5p4EK%^VatNGKs)4UZec=U<(;n0irD~lOPism|2P#4+4 z&KImZictlc2DgH{?i8JX{`T*~D)#xu+`CXR(mg1F8-tYVep(wBPCz47ZQGWHpFDCK{i0Tq{0&*BUqi9$iLBkbLKc$xyBmefpD)%*NfX-A; zKpmRFcTYfHfVT50aEkr|Om$-7=qlMA+C3#r6K-AyZg*#{^$_}f0t#b^JOSCCfLL!X zu525Q8c{!INY|c#aKezu$;zoZn%*EAe9ErpXTVslyBz{TeAGvN=#Re(aj%80jEPS? zCTQb^){(v~e;$F!*Ve8FH{|_>?Zm>3e{oMCiQJS6#|bYn%eyqafI!+<*6mZz^;Ih- zrVgntrqt44mu3?^_p&M^-gIq{eAQ`nX9LTyk@E#P$zY%~U8)By1lC3g?hHur09y1} zniN3HS35jN{f4ATH7ZgQOHV-2Rw?*<4>4OoY~+R| zaH)6D<#iuqAotjQ4dDdD>Df!R@vkr(u*>^)u$PJ48ha)^bpq;){T?Es@3p~@NKLOr z5mY_m(QS|KM;3E#8x1uF#DMg@jr*`xm63Yc6EBG^n4$^KJYY|jX zVO*>fW_-@s6Of%==*K*2LAvB3puQI&Q%Vi9sQHjfkZsHPH0wG-EJXbUm^NU7-qxL0 zfBVNav8==cE?3tked)#t=$&NG@BclZbOLH`d4zmDE16gx?MD>4J9n1y@JmXr4gLhA zHz4x)IqQ}*h4BRR5mPIt&@A0{0{V1VNX?_rYa(leA&<>ZKrEkOPII989>NgZw=U%b z^ah=nv9S7vs!@vtt9MwCaEnjW{qVopHgm(^wyS3<)(@T?u&=W1aW zoJ#|jwnbrOR)*Yb#!@Dh-=1zrJv;$fQFdWc&C+gK z!_QAZym_6U*F#}AmJ^Vr-3bVafe@M2PitI4|B_kMw>W!F2M2bZqd0eTDgRJ$Nozd; zVLO1qz>j+%q(kBfs1g zBP|O>alx{U0BzT5I^Qd|(U{hRxNsn1$I{)~cxVyeI?fqFE;YS4k6aKQMegE@Pe2xh zC!oPPBA99q3{{W<#)zWB&6g4r9{u%CCQ_}Dkvb>=74J_yG3A3;rel+THy{V=Lm?|x ziz?E4m=4NdlM^~hkeW>i;xVE&3%b${9(WxtmiCZ!hy=wMYI*$D_)rqC)E5>S+Tqcp z)bDZ3lhi)SU|k_PmYaaWuU+1_wS8D^h$~2(it9n{lYve9s>Gc3?P-wi4t&M@xFcep zjG0Hd7{R&G+lEW;G~FboC#G2dhg;WOQ6b??I<2fwPm4kwx4qt$Zlp2m#@w`-`xBC) z5gdxC!Ni5Xa+R-zw&A+(wz>1Pu1Q2K5B_iQ0peH}5SW zKOx3A`o`x&vfm-MM)BmQn==QhinQYtiVLRhCA^=uVoum$BBA~amaL)QV+oz(#9xsG zsIQ5%e?B3-HsH5J4B^xI3CQgU<`cCaIsFl`O1X5X!L@gQtW{WpqdI(-o6Xi=oq&G3 zI8ZBvm!Ld}bKKD4~lu}OadT3($$0sT03izPL{rmvl)(74}$3GP}a zAhyR-THEdmi0{~Kf+B&PBb>|3lmUAs;@Irl08Y-=6sADRwRk>pqfsml5C62|Z7#Eb zev`$G4>~pM)2LgY2sNNqBIhI{j?E2iOU2Z3Rw5eqR38{{am({#-x+CeIYe?A-DUjm z=Sw6{sOWUCG_GTYwi9CDwLE3jXcy%7OnIB%aQ+U~=XxBwTqC2#sZ>=EIy_W1_%1SL zR=F8tF5J#R2$CP9S5QUHYl+~|+zQ=I{9v!e)Huo@Sh0ty8C{R>)1V;*bBRg?8xW3A zv92PQ0dE{%p+(&Lod+!abv$KILj(%(q_~&O0km65u3MPWfVwB9bHn0HOCOkmPo$AJ zM;zP&+qkJXu|UyEt|ZIqP0dXN^Kti$Xsrsj+Lw@0JBrvcXT9BoMB}B^yCZyMkrgMP zT3s4vH||&RjQ2FKxn4v%59v;JRB}rMU1Dli7WWz6Hl$W^@%fA2^Gf+@nX=0=KEnn5 znL!rc;l6(7@_sN3x8yUl4cq-)n6ZG4f|SPryC<~Ed-M_2Hjd1?bDu2czJ>n&cWwb5 z30E3&tv>-hc_fL8Za2hg)SZA@5S2N(8`Y2rxF`3wJW9#VZC|4F{LyCaJ<=m-oOD~_ z3FxMO&v4_0m@Vtsqx_b?hGT`8Z!Jr|Q1jdo5ZY50XcPebmj1PqIu&v*(18m~_Zqpk z9`XZK{1Evxq$d@#wJ?u80i`KIaAIKqpg=MyQog+p;cb2%i`x3b2YjNtBe-D!;6o|w zp8y709}SG0{|?U`JqLgwy@Q}IVl2T$Ou#%G=#?GE12|rwoqq9D1C2W74eQ!$;=-CP9OHKA>7gA~P4-Yx@wJ~~u!?W6{arkAMfc}RLz+$Q z$~g7iRT{qohO-b(xC`qj4Rwa=8JSSugwYJUlBh}HfX#O72a~TDQj{BL;sB_P2!-yT z*^bLXbTteK0!$?MY;V9VMry>eA~i|DXvE|-jf;WS%R8|i!fHP5{irFLagw?fo%{ru zf`@7%C*?W?^G2EQg%E-fUX)zfj^riN$0lx_g`j2)2^U#ONRFjw>WAP*(Dg{nyjnJL z(!FbQ_;%t@S4f72;W6g*4($X)JOwQLd?T!hSOzQtj0df255vg-W5X^f026QpIj`0- zl~X{q?Lf+7z)=#vrGHGORm#2On$8Y4kiXB$Iho>zDlP}H}W@OG{BxlXg?QIOaR>Ikm54=vRUIc?|y zT7@~IruG+(w$NX+0v7vLQKk*Xv1Sq8#wgxoPWmRQJfFo=4a?n-OV*`XS1pCNjBDR=YLw_=vJ2p z^JLv-dsew)kWQG`Q1SZYkjIOPvC{VMmLoRyBSomcTfsjuR+#x@DC_t(jbQ_-gg;$Y zK6Q@x;egjkqm1YteZCGPE{k%%@^`S3`*qz?mp6_DZQ}0s z>_0Ew97uS{V^8LQ4-H0D>oX97h>{NZ-Nu6*G>)NGM-{ruGRuF+nd~70XCDy3ok*Nz z5k+Wm0HHPtafdUmQRAcN)n>upy@D{>0DMSfD+xz41Oluo^A6Ox zUs*OYBIr#(P_P=gofsG4D3GT)iBwmEU7O6{yq4oGL8w=(7Fi z4m7;GIcPEMjaFn6TaitP>*tXl(bS{)P-|3s%UyKTqQuW~-j}&*)@VQXjzg79p8yk= z3%;s0FlR73dbVmLgEsjc2tbOxsd+vNN7XZ`Enz*h0b6yA;P78wKolempASG;l~H=C zw8(lJ5xZ-(@wBZ{Sa*Tpl;>DF1iG3OP-VqM|*BmQ;0+QJo3LS}{ zS@|O&J2Oav!gJV^+Yc(0#e=rBfz0z~cA^v-o)$$#q~v2NcThWrJv$UX`G9J zBZ*5i$24lLNhS1W;v#pH5V?VtiQHa>b(d)^onvvYFP%^v2CiDfb84(jAD0OoRbr|g z$3>>!pq-OLW;BOdQqaWF-XbgQBdIU$Ujf`{Mf81}WF;k@W(7n|^q6YY9!+G1RZMZl z2c~ZDM^z*ErjXCt7BuRs?&e3@c4x_fr?^HJq6|XGpwYpn;D0E{d5EVG{6cTm+>$Z+P0ed^L)jix${J}kK;W0(H|aK>D?Y42rdr~9m*2^Zb$H!kmRVn<|v4lOdPH# zhbj_(c_J5Gml>vR3j!fy526dj@x%^S1n69~r%HS5)Yfs++u;DaxqXE_@n9Q##O2Sv ze?#aK*NrvsaosYP<2~(Y2TpSX2=HMpGbNb<>ql+#hI~5g;@YdJ>p}5MQ#Xlju+6dt zXc;R^$M!FXk?P5$nF#VwIF3X+%?^fA~C!bQ1M6pHj+wHF&H!re)8 z%8A`pU=huE^?%O%ra1Og-!r*Ic42qV=X|RH^Ar7auiGHZZhqUy_Yv7+Qi$`w7qr!` zGFbs(NBPSiC!k(LvVW6;s)(`pSgwd!re8Ao*X&1|sw41J6 z9SnakPY+Ek0a^=Wr0@!fgalR^66lEjJ~y6_^`+ zG19mxv#*o&@rOL<_@9K~hm=O8=^ZVY zaD+6$j`&HW!#)0D!~MMvLn=BNUt>I8f4{Vcnr=WHMQY>Ckg!gyDo)>@sVnG>MD>D? z+cwugBXdrY0ZT(>5hMovOZNEJ?Ots^$EA-=dfz5XW!ToQw-{=Mwi;POUeQF?ZLi`K zqkSx;`m{p|9$Qz4dFpnSB0qB-YYa~8e3}K+xEqL8KwKtfquU2IQaiMbdt5cu`Vt92 zVsF#yY{ki@{+&(`a8wG%;-*E)&(;%AmTr_6kR(p*uCGu?6?j|R67#nUYhlGvdMr(} z`#Z?KnL;e+3`{8VNQ53QtUOUZn*|~;(6_WxGgJUTd}j4kZhg|NKeiR`{(9Bb1SieA zgL@aSXUjXrp0pVp=xBXo4Uq0T1D?T^aYW||7F9# zzi9Wkx$hAWW=$SF)!=+c2mgq{J(lMGV@32^Ku0_iaz(qj)mY*l^u95cXBrJ94KBb7 zOi9ZpAjTLXSBd}8LRyqcK#t`AQaUm}U7Ywttv@w|QP}$Y%S7JQ-!iI&91}!y8gnCF z7s$GuLAvNeZ16Q(ytc^%#al@m+=54DBR{?fR?sfob(op;SlwUL@i!H3ae3TS^tAJXK?%Ysh2lckDiIr*$)*$EKqs~?ja?pO8 zLlv+)uB8WtjFx;$s(<4ytF7pLwS3+>9}s_NWIG9r8_?(QS46+=P_{;*Ar5PjXj$80 zuRPxDaO36+vvUOhk0F$IiZ@9fJxaGJt?UimL(xz9E?CmdCyiWdmYaucEia*_)Vm-0 zBikDE((czC8{~?8sID^DmiX98;5U5Y#CmWCGXW#KL=lpKEK#nrT>ENApovsLsR6gx zRZYfcgL*$EtOGBqmK>kEZ;@ogDOT9Z@P%s;aJh+FbqnZ8lZCHPz9Hm@!kuuDF&{^3 z?Et6@%ATJq2<)jJq~6f|c1x}JZE_GxYM)L|7;QL9ki&L8{knV78AUld>QZ}RpWmvj z(Bl>*>|m_Q<6@TpVWoViE%H0mlnN>pqv*v z$8A4Us;d0n$Q(a=UytlHa{Kb5VSjh?7>9$BQGv1-OULHJ5Rf-`E0JEyd%f0G%`7un zX#(h%4i+D18Zyoil^fI1Ub-Rw7me^!jkRFBeM8A=wS&D)f{DEwkJ2(0QzoY_{+iup zF+AmUm3HaEO)BCo9@d6FOH7!(o65Fccb~uRqRWMdo!ki0qwxio3iDhem~a{GS(eT9 z=1FVPt=LgKEV?{c9Bu1t?l1QkI@~uDcIhniON6Bl-sE*rZ@bQbQ-GxWR(q^yA=^3z zq@sN*Wy$GayJxE*R#w*c{Fh49@5JtwEOc@U>y+wTXBnTFC5MWH8`);yx#x%d8Ps^=5HN(aZ2LPZ>ghAjz#UbPYDs@dPv-*S$wrXa&q2VI z3Z~{M8K+5%X9F(x>PI7u!21wTu&Ec~TqokW*&|E(Pd~1(WeO-`P0vaO>r>xeE^Cgz zYTyH9^cq-0Yo^SD-*V*TRh@tuJ!{P1VKmve{Pz%QACN327Ow@kDY$FGy`(2h;SSUu zCLmmrcZRy5OE&bH)LB~NcX~t)j7V5^AQh%!|JnOSBDqo%NpLwrg=ewX<4_T={eJTy zHs54f+PRfb#K7}%L~LEsym+a%quDvpnT_;4szDR~C9?hBGCNF8?7m^_35fd(?vZPO zGucg{zao-0=8;{~e_qEr&XXS_yxkTQP{!uBpmwg}0 z>{cwH5#Nqf%m-&>iA!i=ZtyKMHR+k*apQBS9hiVZFUKw@s2c2AHmB|#FY1p`{lMYWxksPzuT${EhSA6e}3>zh%xs~ij%we%u`!QI5}2)#Q-R_rp^ur z^-P|UHJF=;XN3%>>o;DxmQ$nkx~5%L-bPCRW1m71`!J63dFJ8es!)HBDvSA5{%Dme zKm+~mkJSv9 z`qYZR+mmh+@rI2Dlqy>dyvWkU?4=va)fE8}@=sn~Gl~8fSkI4{Tt7rBqhIy=f5=~- z$5NY4KtKx7V-efaxHn85)WS3MU^o$XlBb-i3k`8o=z$YZ$Sp%)ncNS{)E_;=rePKB zkJ8PMD=r_n@ILsDZ*`lU>-MQ&VIN16MLz%?eeVZs!GGljS$zYW37KtW?rxGXyJt&L zKd_H;f}QYgv8LuGh>0Eno5eSBMC$JN_rPhKL8=d$+lg?`kJ&BvENqfV@|eM9!i5;~ z=&jR0{!I1r>Q#m7U$#Qx^ZGoX83>`NVjC5m;o`HP&a+{}u}rUYEAb=F(qw2ekhs)) zYC)4q`-$7$^d_BqVJ?SfcNb}|3#pW`7!R)gOL@C-=U&xh zRt9Q8VaHY~ZD8D;k6Hy+3HGnwt45%l2KUedm0bh2w1Pz*%=MprC|Fb{c7rOGMdg}OP*xwq#^RI`_=VlKL{jcP3 zus&Ir*h$P?bQmag;~mj9au$$@r&|9F$_(W?oJ*h>fx{_Ri#O#^sl%szte3o&SaSbl zny+T`LGuFl^|~KtykTt=DDC$&TtWQxkKpJtkmt66=RoCR@V8#y9GbPlXw)r{1ju9& zf7o`z%u0>y${mMk0WCc5aV@ai^L~*`k)e=vysT@M&;Hlr^aGZ|y;9iNw|8+f8#Kq? z4&RZ*3s28CVgR$nwV4IHbAn8SqwajPk8&Ef_-b69AX^GP#rDSx9!q(g>(AG5)UX<( zaK{Gnpz>{>M^M0(gxjNj*RiWd-E%|3 zu6^lEEX?3q{^Rf>d=a zZZ>Jz>Tw(&8*88U2}sVN(*F@d7!_}5?Ck)KhTybduWc`W*G=Tu%e7$(`s{sohqj{xt1DtOBStfQMCz4pJU$#KE%29YXwQ8mw68{uQ8XJ`0<17+l$f+n?{=r%6}9} ztb6#nPsP$XbQG$b=5HLnG=*iur*x`!w9t)O!e1Qe5-jRhrQ0ZJ9_6zwzSOV5>V$#N zjtB93sY#dY8OXaMd!SIC#Z?|u@qB?o<4_=GV^vD5pz7<~5B!v94(1Z{k=RONzIG{K zrZ0p$)PK5W?fd60P!hgRunBEPB%_e8MQp1q3kYxdg|^>zZG?6{JPNuU6`4;80?}`O2~k1*9mB*UY+WqzNjyx zX;Ac>37v&ng4cEDT`&Dwwh`j_-ZfX=nVE%I1mvk*{@9e5w_wA2%lWX;T#$GLseln0 z@IUHAC9)$3mFwv&+RlzwZb*)1YG2FB*1{!*Vs!RBKGkwConDrov)}0#TXY^aciUQo ziui|1a}ZZeF|Q)rhR-ZLrRcm8g(U#)Oj3i3xb0GjHa2x=%0LF}4X0#gq8{eNuB$N3 zBjyAU&JHeTUrG6`W zxcv)Ff{(~LoB1J*dc$ljy8iJUiG+{yq4x||ZDnj=odbR}cG%^Oqp&)SRi0efmdH<7 zDw20a9IrCSc9`j)6NmT@U=-OF`*{!OGSw>sdhYk&8x_;M_3uCb7y!k`o%4?mPPYu1 zvV5U?bsB_D2S^6`JahiPf(X_f8*E;^Kc z|J640QLUp+I!4`sVI3@VbPWGj~m#}dI91rC_Nwdo;~!#%8_mF ziHm%?PGvbpuad4jgwdIaqQ`DdNI=~kk6U}O55n`29pH6W3ShmdEIEJW{c;zH)0UH;WYto9Y1f+iodN=tYeeSKt!Tegr$t|0A(V3wz zBL2|TkxW0VCQ%wAx2>WrT`+{q3K3s(Rm01ZSu={xv!6-VJO&vapksD-uaCNyORXrS z2Jo6gw>*)b12XmFKJc<-GvRmF5`x=H-g0sq12_O9tMU(<4bPPCWQUyri^ez@yo>8DS&Tzht^3N^K7byjV#H2BO*2eOw($j_1GFpkcd_QRW&t$*0YUH&yF+v! zt}d#SB9c9|UTYMYAVimO`NzxzImPPm*p?&eB`(}Qby>O|`Du5!Z~nuE%OE{`GGP;P z3v&iK-gyGr8pTpS?t(}PYs@Dgm&s@#FAE@^K==mD27s9Wwxv00jTZV+EcfHFTUhjc z<_M#2sL8l&punu}rCisBpx-I+Y2Q7vikp^=P5=EVkYs0B`-jEJL_! zhH%R}pZ)TCmuIF15F$s<-)2+d1L0fSxvVE3zCQmYaXYtP1w$FjkZhM@;5+rJ$6Tja z`<%+NpGI8%!2@X>H;kg3%k|gXAcP2yY{mQ4^_xC3U;cFyY*3Kr@$|dLf`|9!jUtUZ zo4I=wJ?D9T<)jZgNf^K;{1IsV=bp_u@NP>#a9@|mtyouE1penzFRtRe43Pi z`;XPmJH{z{&@1>;Ee_O?zndb37`pg(CpwBm|wRnK79uP(ELMj_xKpaN4p8_cr53$g@EMfy($J*pq z|CL$PxO(;8_4)JKU%;P{h&f)#+LU~M+l!|k7m#gQ&;8K2{ZOmX9^i5yI$ACeEt@Qt z%5DuhJG~B@WB9i68K2v2*Mnp`w9yoqbL0z2pNL3WE&yr*eu_&#oFhbp{j6)jK7Z?w z_<@6sgk3d-Ef~rfS#<;Xg%c2Ll(HgCHc{}Ly+LE84CX$GbX`ce&U63ammn4(R5-9n z918!3OsiD%7xm@ZW(7ul2A=Op!gNOFgEC5rGF&ux-&S!Pa23GmPC#wXpf`Kx=fZel z;SvQhv;O5|>J{-P)a0{wz}a3Gjv4MkvQV{Y+Zl_7Q|O+QI@GO<`8Z}5*@${&Bok&n19CZ3*2(O6CMyiFFe9)cqtJ|vkqYg9uKvT}?df2<%nzV( zcM3=2LQ6DWmr#v+p0X$u9wPf^ppZ}Z9gB^MOxgonAf@%zok#_;68Ty1^Ex6US;@bn zi(Vs&Br%Yh9ubcBrJ`fmU;i|#^A?9W$Y zs=?db3t$%IfLeAN)*0=O_N*3|04d}wNMx)lbdolStWJn0-wXzi9hx?^D;vvpcINuBWzMTc7DLxyvNjv+Y@`Gn1DQf%w*d#_FNJ%zn7MjRq( z%$KsYztVo(^7E9M+g5!}SeBbnm$0NPxlkSs9eg(Lu@$Qtc`>Z7ZZ)>cekQGCKm{E} zOm(3pLFp+HHAE4dS3C4f^^}R`$WmRh#$|0OMIC?{CnAC5<&oU+GwDzL-7Ei={q|^; z%o^yDaEk<9vqmI_qEWbE%&y1yjfaiZmr}@9K#K9M|y=1%2x=WP5 zER3~$L!hr#ffY@zTZIpV0>z<-Bt&S7tOZGO^wY!BmlXmbdd4qjo@#hVU7mI(3jU!QhI?Nar=MOVsEIWUZG3&r+)=ap=KU< zIL!COtypUZc>>^sV;NGuaTwT%vyD+vTF{p^0G$qJ1Sf0-*pX5m`;ZgpqsP8gulwrm zZW2*8Y68D9p8=T4FC#Jlvdy&^HKL;6`c;kWFba{S!~V49AZ3PXHhZ=h5ogM4>+q}( z^{2C|x=QU-ZzW~`brMOqB5E;W zd%h&DP#QA3AQUs=yw5byg4M_`i7KL_9P zO@{)+##Tc}UPue;n_}bGC}EZH4S-k^K@@0~Xg4w|EDtHr2%h^w8=Bfq7#-b~JiOgw z2A|O;y-gf$+~)XK(fQgYZM>@MMKR9*SJBz$I`o$7XGD?$eo_ElZ5T1@t;~DJ@!5hR zBg+QZ8+r5vjTPsH$mWfsJ^Qm-qdr`DwtpQil{+=&R>+V221Hc<-vypM@RY#j&)>IJ zX_o1S$2j*XTcXy}Wyd7`fJ@c&H+>*UZ3%#L)gv*PxPKU|N6X_RlQ&T{OdWTG`NFVe ze|yNUF|#% zVe)toaO!JJ+fV=LiZ!e|kq3M#SaDo|@mU?1d$NphxDQ!2A=;zb8)Hdu0tO#FRpTn& zAp=RCgib20?%q;M>;s5miZY!ckIyL`P6k%}9FT!MYB$K4bJ#cmm7t&&R?W+!H#HUS ze0#`Lg#HbS%DR-;9(s1<1snbM82PL%ErmUit)m5wMHIv;&3bw|^l)$_FQoH}DCi{< z*Zv>X=wbipHH=C7LcgMrl6i=?+7J*#I8FlQ?=EAgDYDH~MZEA{4}J?5?3B zKl?M|yWlZ(H4PK*|5fB%WZ|5qh8Kw%dXnx;FUxSlTKtKe zw^1(;2m>XGQyAhTF6Vf|M&!PL((j~+u8{0nlCNVp?(*#yz7IQQTLQilh4Addf2RlL zVeDPEZ|_Y%_RLPphvP!>Q;(Oas0p(pqdGZ0r@qtf5^f9< zre2xUA?vv=RJ?!!ae2`WOs&2^1Xtlx0Fmk;UcWqzZ{^OJ z%6S2m9w5)Xl#Nv0)4`x!DiIB1gzOu_x}UO4vL=-naFf!-oxi%bpY%aUrkXjEp z=I06U9FNb18=8#yNEQsA7#M03|5+ffDXUv32fFN5g)A*td^w^3}pQIT8()I4T>V$bW+6bpa< z#(x5_^2CMlw*X&&Z*4rtPtaQYdk;>!f9{LIFY|Aq1L?4-VC^Co3EA4(MFrTl5>T;& zeGasA1(z<}7~TP{N))rf&So;uxPJp)+WdzT&g=+3Mg%x`y^h!A*gB0^lr$zCsv7L< zsi%GauNkeA#O!!!-94{T8wRORSJoWO9g1T39h2mjO&|%Ncxl z112*4$ym#kwU;-4O16GziD5-<)%-Ni2|o2O^!g;nsKyP*Q5#xaI=m<@k9%Bq|5i?Y zaaTa@Mj#;DOK6j5PAur(DgJ?&TYL_(K&$u2l&Nz{qpp&)_REW#90|#I-f5>=UNOa8 zx3Bwu1!9_Ew_wEWfKQ)&qS{6a$<7-GTF`5uzutchJ_NLLQLFc#IpcS44}#SNYy8gb zR{O&YrkuJ6Jl}K}yhK)9L%zUk?Bw^ouZ(zxBK%n*ou+KAZBPxPoErQ^6bTtf-{>I+ ze2w_gQy>&WE?D53bLJ)(6D{i0Kq|~w^4DVko~^GxG9OxeIg0oG%v-$v`S3<}skK7| zZe}~aJHtn)W>og^A5GsTW2teI9WfR%cQ*_yZ+KZP*SMB?d{(Gm>qQ*#NTBCh6RZnX zHQV@AK6%|x0PUj0a=sT}sCeU$3`Fyl+dGi1r;k4f4MHSo2ufmBS$L75#YUo7PAS~^ z$jYJPUVyt~Y2UcgyAp8gSRg4X)8^Ca7JyW){PTc9HH}%_KIv1=k}I}m4>C)@*<9chF+Nx2~pxSn}0rn-43#MpEY&rAA4Fl(#%gRgS-T(A$GE4?-C2OTpch}6=C zsFepjR}?4ZOV&x-A07?TU?%=ygvlSsNd-R|^QtppcdF64enV2_4s2zl9hQw25lpCq z$^Q@>%qW3-f!;$2X$0%>7skfV1Ac4_0dFEg$& z%88nL`3k_Yxr;`_oRK^zmSDNYaPDcp;<}04!>QIZ*wGKzM|6C!Y96$zbaGOY+4<`u zP*6HC^h&3a0gwLyc7*_CjX^Zj6fImGG2bB2ng&Z?4(?}=4*piIwibi|->yeVlxxl7 zl}(a4Jqx?wiFLfFY50|<^VChVmJ-Hj3u~1dzVJkot#9uy3cPlfiUGFGj&eJ&oxyz= zq9mkSmwd;aks?#&#TCDCtETYDJBO+6+Ybp>__q&P*Wnp(R(Wbr7Zi$HjjC2P-ZyL- zJ3J$CEqTf>@oDnij22^MM_6Pikc4d0-lCnO4L9)T7c5|6Y3y~x=mq4hNpEtqv8dUO zM%?}BZcK&7=4f3rb0?4%aE?HS4Yuol*hOj*ujYD8`!}$Fpc!ui!< zWuLc!&rz<5Yv8?+2Joapp;=FadqT$I4DZ_I z0CNu+=yViPr>8*cYLrG&=-#^yT-lAm$zO6d{5{;yKOO0FJ=Uw|Zty8_d)MIze@AT_){ZH+Ow8W4TN1>R)1Kx-$dpz` zu_+I3p@Hf~tEzPicj5BH2;cz^I@bQV>$9-S(>2)e!-H{oKL0sqmw1GgV!F?d;Rqv=%|@LD*^K3j z${tr3#bv%X+d9I8g>t)}CkkB3x2aQ(2q_A?9C_swdfA!6Od2UF`Mlt4Nvp71-#hUmprPU>}SzO#IeB)6%DfTW`mQnd}EA{ zMfCj>kf|{A^*qgIrJ**u&`A;IIQpWXGJ{-o)tah`WFh+&ZKP|Y);SUC2o*Ndbr#DH zfqF$5Tsn5)t*UO5N+#SDOUm-mYhfQh-_yxyo)`RtXx75`J(g@JEu7-H{F3q!UTA%E z%8_ZRX&j@{^|W|?qd~zmT}9{pvW|i5A3(R4T83a`SE`H&0tOn{6er-{eF{%G5tJnlP5R;17P*v-x;|mp3l4T+-%o-doG?}k|ps)#qEV|<7 zj$m90*Pzsa4*)&TSQB=9q15yCy4S*YTb0QV+P+$I-T)^q?0CXRzLz)Xn{y2RGV5%c{a7%DKxa?=_(%+&h_KU&v`jWpA+Sr z$X43|czckqj54%SS7}TVjGrm_ap-EiWIML2z*it^J<~t(pl2)rv4xsMx5IFW{_J<^ zIb6GzxRq$TE|lFfS$3a-v|WQJsdL$+ackg8mrXJSLlS5NlxnSDZ9yYocbg9H(l_te zhT$U4lHN0{s>je2SXYWVg8bPV(=qc-JTOZ9zpyzY7pe*PcmzIQ3)8Re$tiPaEVcv7_6{ zCN-`U@i3&~#S8VVgwwDFkpK~i@9xA4T<%M#Ez&%CO0nZ&mH>V%@>ky1Y3sNj^L0(B zb4S^h>KuIZFE4#p@wz*>(rsxQV5`m3l%Ojo(|i3;I0N1Q7#(d4@DCf#B;FmDG(5@~ zcN77VWy0Uwk@JZ#dN+muZd%Q*m-a9iCtgl~QDj1Vo`=X>{`ZgPL z=`sd15R3jGxC>pL=@zk71`BN(Z9T&InyKd!a*p$8(A%B))7qC?_q()c3N%%>jR2^qZ<9lXP)Kzf{(shhpRuUK}f#wQp|Rn5)ehX9_P zQ-~%J?pU4P4(Y3nA>wjMdh-zvg+x*zLsd86BebU0TYi1;J!kgaCKNxHUel}Wdx?Th z&6lY%SbC(Wuwb;oKU3WJrK@fWy9Kf}$IB>|1TU8tWl;~R zKWbh4_2t)XLy5BzJ%)JDb(@$6l>9hRDj;g~*_-8>^y)2#Be(F0-USZP#^wiQ)NI?T zSB_jtUlcER4I+kKxVv;GV0){oJ5c|o+I)vDb(V@xGh`!m$tunyWdh~Bip&QHkRZBY zHhj6AhTT#kaqOfmq0+#EO_2C6?15ULlq+dA?{|)CwcXTX+vQ;2$&V<9`|*F;o=K06 zisFysq6-&LU;U|M^dEuQeM(a!A-<4#5Mc5^4D>DU1Os>sfFK3i9bwLYEPAmUCiPnw z6z7pgslWK896wG(k8I(ZPa!G(griyKoqEP_BbHPNcJR!N1A?=cb%G~Xyk39a_^Kh( zG7uG|ho89>(#>V!VNFi3X?gtk?OWe_A(HuTIm>1=A{k{Qc8w3QC_BZZ+0xT|%om3E z!R@KF-jsdnP+nFc$%UgfaH0#ogv;|ij>sksLTvoVkzO~MI`@}|r{~i;4=gFQsP6!F zaO{tfgNSzhyWdfFoiR&$-y=|vKaxVwMhM+=vL-lp>h#jhB#GYq;`V_lmp6Y*g`e#n z_VMrZGEO>fN$g9(d#o~S-Cjx3?44EN!I}A?Eh5KoM41xtXaZl**B9k%^Ujq_o6yQs>p+n``Q~b+=@>G0aQ+D_5d{mmj?gI2e>W6SgCl|)v@Su%1@B^lYHmbi1D(AO&Pc+ z$8VNgo{m;B;sFcvX;e(Z>aqg$ljb)SL28r7W_7GJs9TyQ*0fJ0fsG9g(9LtPAFOQ( zyNj8wm77iBkOm7WX5)aBkLOm*eYdjfSxWn+LJ`;8!raWCN2EAp-zgdyZ}K?tRxF@F zims0Gm<>l#5}GR0(|)A(gT?yOGr*n8pQ7^Z1y8k>_hW4eV`)7VW(;3IkiP4xl7;_a z!)a?iI(i$8`!JJRmsLF2OJ3*Qz7$TokHkD4E%U?chk0yU4lk0-Abo$FWXUmo>CXi} zMSD61Wp+-mX@9`tESd$7bTZxF>g?AvPR{BiSOMmMVC401Uz8d zdFU^npmlXu3XHgcxD0Dd0<=Tok~qFrWw&hN=A>RpshhX);cT6>C-Jo!L-*8rJzNEX zedrl(&{j(l_WP<&vzo#H-8I{{?CIw-DUMH?uYJM(gyQpF;OFCNlyA}XbB=7JS)mp# z73S&3If6z2nIZYSQ>3Xx)#7ibh6%wvh?UvT%CJxL_N;|+B)T<2N6%#49JSxCShG?& z&$J=(j`=mT^9BV7>;i$HT;iLsR%U)izwIv`$)%%G1A2%G%nR_ZvKR~?+JBcjf4@)9 znSqAlMLdJ%H@BgSh_{rl2#Nbu&fmlEb%-;;( zWMvro0qczoz}dnCp@Jx#0YRz5F(zI#-kQEQ_b}g?S23-I0Y3<;pLo-%ia}~|v1lAV zNOYE3y$b6lDj^P0(C{;q6nOuv`J`huq+bQUq!FFbl4dtV{=!mF|A9qhaBFid5u`#& z9X!1U+P<&%J6c63g8IJlasbk%@qBWN{v{AHQyp<`RCRv;;95TOy}J*pp^qd{CWK2v zXJiB3@n4aVv1X1A%xctb#lF20z8W(*{Ey|OF8VFA8{n9yjFF1!YS@G6B|{#^rsKB5 ze}`42`UDNO?qQ#U`S#Badtju$jv)z6w04zxUNgRv>sBaV7RI7lXavSf;V9Y+g4dqO zP7+DPE-8Pc8Wd%8l<}3tbpFTD|6}>FlP%|>Pj%JHpy)KzqGG%);v6E?Lj?Nwk0APR zoHb%V-D9+(J&YTrlSwgb?q5z4jAy>?cb~O!UOrVr5QWNHE!rNQOVY|z0aXY`)F~sg z-JeGB{tCf6TDiLp{J$$|J~bs*ZcV%^IGN9L{p{JXaeQm>*K@v+QvgK*Xp98K)B-iE znzJrJ)cTb&@4TH9_;EYo@`zEn`MHmJU%T?(`miFN;AgQ75Q;Q8g@~)AvIofjWBEAx zq_5cFR_;$D4?9tDy*q7;-nlJ!g~E~vKSg29mSyK+(uazt?)Lc>L-LJL= z-(mq#B>;^l&NiOrTsYS%*0NYyxz5Hsah4crR$W@8c9!&!-|);8z2>XuqudH=^-7)J zK3sn&6Ir#CnU}7}*Q;%b)cI*C^nJYIY+Z}1vB*tQelT&dJ{}W{(gZ|elkI-TZEVaR z&V6`$`VidW{S&#jAw+4&*cjP&z!Cy&a)C5M9D?IT_iu!Z7cdIYM^|7gYFCjUc*Eu1 z!%(?7Sjd9Xetl>)lpG#6Crmm~zc;npU{nUo?e>l!@eQM24)t5~%LFf7s0!cSS733{ z(@Sf7>f5G=n|NWb{T~5)xtfV_$~Mt*@Ny9zEdD;l^Y^Ujk1a^GQF4@4&NX|gTuj1@ z=f_3p%@40&zJ~~Hw4(}02Vxc_<@eYa-_5KYK^+5);uD(+iN0=ek2#q5u1y+8kQCR`kn%-A_5dp zN;%hS`>^mnFn3p9Q5_AR2V8{;*KG7m$xIf~)m{+;|IAWvZpUe~mBB(HxK+yjnP8$0 zOg0NQX8uH5lc~|O-H zlWqb)Q88ImQSrQ=W;WJm)vzOb zHE*ZP=FXZA&$Z&El@i|r63~5(V;(K(Fx!AWGML}s6rFsn(PtC*hBoe=F@KJ1S(kEs zN7ab7J5|-~v{1aQ9i%PA#&LX^uDfp-7l%ipgtfm+j-qyyNZfDIq(m1hC6jSy)DDW? z|GTmO*VjL=BPa=cmE9FM?;m5k^|tDAGa1;3uqknNvMl9Z{zdylfl_+tM{z~loT48+ z^5>?w?T4uEF#L&baxXal-Y!smzl+VUIx)S9V54}SQXW70`P6pD(UXND8B~aUVC@v7 z7{_WPaOFvx>m`-dES9MYO#fj+I3mkxM7e!--F{V%d7^9|b3dS-cBE7GfS0Da^&UX; zYbZCxFEgP-%Uc96Rn%DXy85jfU881+f>Df`kxq%H$TpqAJ+E~9$HImENH~k8{(uJ& zw0yp3Mxu-{?R{2@1_Sm13=Yp{|^iu;VRKr@t+4QZQEU#HRY#%U; z)fR-UVTq$Gcc;?C>soTd`oKPE>+>7~Ulxe&zN6dQs)gWg{Df&KAwop1!4Dz14Tc1m zTLPu^s@5*i>bVi(~Ys@9BG{+(lo$D%?u9_$YmTm#Ucz>+4B zcNTX{NuT>Tlrb54&(lC9@i^xiY6%RDLCx5X_tm-V0h640~) zjhwSR`VC0O-^We=P~K}soHa*1qBxL!!o63-1oH#sg5sBZ@8uRK?R!Q)f0`GzepsYr zKal_*$slxpl$k3XWS&E2cRiyuE^}9+IkTTJkK$6Piy$rWcWh?yL&+w$g{IgL_4$u7 zC!Wj3bEByrpD0~vVPPHbuefT)wA{>fc5kn6a=AKRTp3WRb$Cgyx0)mAE_Kj*RqcWq zGODTO1|FrAZ&&tvMX+QCzjxGD_|2BmTP0!ETiB6JiUe$}dIoz8-EJXLO_Kez(`jl% zl2Yzid|IFte`}8A9_H4qM*9qrT)XiEGy2VBT&k)KS)ZavI0O`{@l&2Is#QJ`-IvVQ zf5!L#*i@UnatSawiP&8|R|nRAUQ2V`!gQ8KsTc$J+g4DRJmgV_~);PU2oW-8Zf#a)!I6 zkFWH$oa!I9Xn(7H;ngox{kyP&E@jfPdc!xeH=P1Pre^wUH7?5aUnp47_q5FrXZq^r z3{0VE^ef1a2H5^afeJy0GKVlk_|2Y8CMFju({$%27&E@J)l zif=K!F=bsrETKjuS)?w(8M~*GXI`W1(kb1Ig0};I<2`Qk3k!~JJ?vhpuS|rI11TA4 zw;bTXB3C{}BzWZffHe5}bRE3I97eJ`Q5$IruV!QVdf0LTo9Vo5D**8^Zd5}1Fs|XM zhKKNa{?&N~-=iKr8@ZP>JJh@Whg)jWl#B>J-Me#83fbWo2$cOkF?$VOJ^*-14A_|7 zbuJRjfV25F`iyX)B96h2OKq#h0KR=brYy_yf~--=tjaxkUr&{c3Qphl=Pk zyazt5&XF!S?Teks|HHL8H+2tmqgT-yz3P5zjK~6T75eB>35OQzl4MGErG<+k8A8&j z{kZAhU;=6LIynKsGtB*uMb&-a4Qw;`6#9~$dSFNQ!~~4Vkw;TT1WXYA&@^BTt|{YT z=nKd4%fQ9*3r2TQvyZ}qE1fD}4IU?Zp@Y)Br$;d*!dL8Gw0Bt9@3 z#C&`=KSi7Ivqr$-g|9yW8nCeqwx=xdaRW0l_-(klH27;OBjAazr+#R{2Fr(j^||j0 zzN1TdMjocp{z2HQb85ktF{_C7PwZ(X#e=f)b+QirFu*6 zFBCCwFk787HHap2*V3Ic-@((fCAhQ(Os600dN0`c^V9~f4?NxECOYG9Cm*L3nx=>N z^bSTe=pH@OrC>NHFI@%jQ15{%?UMX$4lR{8 zoGncRk$om5;ZSBZ5f-p9RuP_mv74#pkk$_}nPq}>B+awF`X)f#8=Q;WZyYf4)La$k z-46wiinF|@9wUvIPvzSro12S4DLW44r?7NB+|2A3GA6J_BFMW*q39orqRF8p#@XZ= z)_!2R2*;j3egbFhFt>^s!W{U(@!4o7MxJL7ey!`~9s|6~usX9M^DY3p2DeHpL z^X76)4quwm3KB|8RQ;t2a#-IOs47FlbmkPaXd{z7ngqWWmV`f}0^WKNy*u4Na#g}( zMjrZved7s42%7tIQfE$m#_mgV-N0rz%St(oKfLO;XHwGR95$ORZdNUW0{eBBGRUQTxV>rFwTM zI3YyMrh2QFJ^-tn#Jl0R%!a*>P#-d$ndxo0yShnYNh zP<(j%M`5j=k1Z+?Ru2;}U3};NwqcN?Y)e6lDU3{(>kiz7){k`WU<+;YCF+Nrqs75C zO;PQ?`W{hwP^zTcBA|*Fmt(Bj43RgrYj*!nuar8LTR|K&>_`2vMhrFjn)Qtan&maK3-qYrzoY`AwQn z-;7_Pr&5b_&LvsJwOU$Fo?D=B?*ZITOcLvT2}^@@!>=~I9$0c_7Xh2sm36xmWRsPdhocng_~?L&VvCKVzdB4$j*T=$Q$hdnqBa z^*Rx(^l95$T-!eg4l_kqBp^X zv`#t**%mavznmS$!hYw7^8b#G|DVq_o-`ajq<}g!a^+ovo+DW1634C|oPZZO^EIoq;MV%hv3B?6iaKG_h>q~|+4s(z>B-s{q z!F~<%G!^^lV6=eUlSQVlRXl{j+Vr*zLj>jPBQ;9}h$9nY+@O*5$mxQyN%8LH@vxHK zfhYNJ1OwypBv%lP%fM{j&G`eRqZHm&#?rZBr|17-3P6-Kq{|!}ta^`r6GGbvIbwx& zT7eQDOdY9mB13}(cVy`>+akX^u&X7l2d|sH7Z|1+g<)n)!%s(c1mn`sS$dDIM7Dx4 zE9D{(K{)BiyhuUM(vlstX1nJrD}?VekByKjM-tX5yZtv$yLZw_1@w~w3TtD~1)a65R)rrZm=Os$i*LNKD3PWUM zo&l2#V0C@kbM{rXB^Q59?I*z znTN&cYR*6+cHT+*PGh-@f3HaNWjsRLne8rwXWDfbY&0(nL?qi9gQV%omG|Bud9G>3 zAV$I#l_fAMALP-S_&N3W-?Z+gVV4(HXZ8ZHMP$q=JN~n)3&Rga=tC8qa59o&n!C6@ z#aVULEve@97uIg3l6uo$KtbMcM?aI<2(Wq>T!qyGCqAh@x_N@1=^rv*0;62oTU*Vx z@oWgyc?B#EZ4hMV#Si||KbB;ihXR5kwzo#g+_;Ve4EozP9dbHbrss3M48W$tF-K%P zeG^Pb9$!>%PTiXZrk?bdzr}>g8?Gtf>0J6V3I1e21ewo0)?sSHwiRXw%LMAqpp!O(!X{Ru6E8wk%dfrxh>8DID6%T}3PDHox1@5{3#aEf@~`nimU z2D0oUD=dI;KGq3L+xb?;%kbH>-C0)>g6f%!dWM!v2!HrJRC4Z&@;QeJ(Uv)NpZO^| zH`vCe$TyEz&x9jgu9~604soW?PNL9#!Q6C7lBi`BU(FkOPduA`z;DVnNml2@5au*W z-&s>PzO%N42{V6;p;^*h`$lweO$c5q_iYa;acC5`5f!`EPI7x7W@a5^n8k?<#+$9#~H1WqKUd%mcw*feq;Qy+Dj(|5Hox zQ-1eedfyv3V{6qk21Yb?34b?zBAmUh%(CL9;xYKVD(b8{--)6f0KCn9!^nkWq)fU} zk1Uinv=?;;c2T4{~b37>V9r=ZA4*@|2CXb4s^L5vs;bNo^`%TM) zJM(sK{9{?V>yX(Gn=YC<2I2u62c@(TK!Rv^D+VVhnOxV=J$@TXkuF>N$MQ}y(SvYX z)~om{uyfRY9CVC++2}4qM;=NIbxL)iH~&5K+iTo0$>fFw*w0fSMAW1y*e)A2X7feD;4&VH#ad zJcj62HVT2d;NAXV><>$kyC;1C%fJ@kgGtov_tzuC7D?%;1qNmoYTaQW+ zzCkx`!TzRW=eJs#;wNKRiiSK++)?)8fBc;u?rcJTP4TykEJALAtzwtw9r#bslMWza z+!A(Ss09>j)uqpZpOZ($?E7+}{R}Q4ez|ya3^PlPVeu#6f?9>sE6#xH^`aLCLm|zh{H<1Px7$O{iiuuzo|6Zh3kg2@c(J|r7x+JqE0EHEjw|h6swrY*IG5H2 zCk2P>i|RRQOogNE64X%j76!2E1Y_n7aZ0#x6ceGM^vd6Dd}Zi&!0y${C($J|191LB zkKwFvV#+F_n7tuXpu1Z(*b%1H8@YuY8Ks3)n}n$5b4SXUVBQ_@Nsnmvx6{eSYEYCr zKDXpyX`544+gnkI3t#UqT%dn9#G7cYbI**0K17Z1LTy`5^@k8KV=XfQ>z~pxz)q5b zN#YL*1}yLHy@AJGATQd%Ht=0cC<&!VlH9)8Hlc+L!S4Pj&7BV%l-qK_4$gEuH(6|LyLx1+rAM{*mmYrRk%-19^M4oU=)w?kV(cYITdyV;Ijmf0d$M%h(V}u7Q+MMhFkDGrxB3Dx|p3?odL` z$jJ$LD>#>jL>kE@tK1Fn8K?P$Q2NHmvG`X4uhzkjn0MP{H0l|=CLa(QT7}iCZq#Uy zy05*ZY2tYd+hafm!D^a?q&O%26i?3iINKSz&0FPG#Z5ze=oK1cmo4>$sw3s0B{CqD z=⁢<3Q84efyRTkmo7fY|weBgFczBFF-Ysl6ZFv{Mr&9x04S~lJc_GT<+ zhuk9g1ett_e&R)+~r})`%Ul)mqB)OfJPmial z3d4H_%{gb6QV)v+$`}9FkLw^+_kZ+g2^OO*lkmj@d`#|AZ~VuM0kc(EI+xOR}}N0G5~!@xhmXk4cTR6$o-Vh9&N*?Cx9QZ^{ zbobuReLlh654-*b??7}~hb_+hX`seB2uz1zjyV@PR_PMj*_Lelp1^M5^4`W{=v;F3 zH`o{$lB~&lGXKrft+0C~RDE?;E3|<<2&;6yY86n*P74P#e}u0{ z#Ik27p!-~?9c<^UE^xOP1WlUTX<5uBnD9;*BVz_03_7! z`h#DT`>qgf^CzsUumr+JaWm8{n}qgl8uk(XDzUE=n<>E;I6^=@z3j;1jB|c~ELwPBb0d<;U`Yfni28-zVkf=7XRS@Z7E-?-ILQisST=_E@rN1-8zKJ zfPAumittceX3S5!_ZR1wKK@Soav7W_vSq;dfV0_DlbWTNrzR%m5r1i$9P(emmzp&rBY)eyEeX_uxIA~fGo?+HCdd4l%K2NdG>lEy%@}iB zWJDoiEfH!j6&KK2jZxLcLi}|O7xI|+sgqZYh?Tfem;k|xo%sRrTVY?7cHS;Dk2x~Q zcSZ5UIiL1|wFlyNK?-|xUCvX@(Kq8tH~#DDV7D_b?4Vvi5{dFiw>K!595&Z@ z6@T3D@(P%=NrFLPmcDK?%^7aFNHZ`G>iWI%+wHUx=!EMyWD||V_Wr%ccIa5E>fL<% z0bc8oBpI7;J)KgSgS~n2%S?w>x)+?HRh%!veKA7W?J0!M9%P7ei$4Rky67}y#&p?7 z71L_0e9*7Bh(|*|H5#cu-T+({06-I=XfL;`dwL#IWqsy|_N(HE^Dw1LG1(itKmJe? z_7%plZO@~;JfKr$uDeIm;X#dWS{sPi3g>?;ubj@@K_yy)_p9t+@`RBg=6A*X{AQ%`x<3t8SHrAXn_9CpH9U+S`h{-6Wv<6D%+Wejw=^@?AewZ;$S2vDqjtT$A za@C-kbDMmX^x)B*UU5fHt0JFo@~tY%-236Ng(rOm z%WEz={7#ZJVmLHgQo{LBk$P z(D;NauIyFSO_<22BE5w7HB9i}s|mWDUpRp_QtVb)Kywn=cLBvPey3U8_J`82>$15` zdxZ{*?j)xap#2$r#hoOc15SrvdT8e>pL?wN2>B@+?5ds7*MlCQ`ptTmszrky@OgR5 zcT7CKT_j1<|GW^TYnzrUShw1z^DDbF^7)lG{8wc=7ncHR&AQVNsJq;#s7`HeEk zy>+ohiJw?T;z0fh+Hp0>9fLwkD8gR|+Khg+p;AVwyi`FssM&l9iL?;@cJl90-%}_V z8T}$=$;AoF)C{6RcK7vy$?iE1&0zc85VhShO8X4BC-bwszxW&14_U;%_jTCbm$gRx zxgDAEtSx7vWzRVkN)$ECKi_zDI^sL&N@XpBJ+wvn%GA4Em|$^|WZxXEtN_!DQ%xbs zWI!jXW0_P1d)adi*S?gJAFCP-wFhMkVF>OrVu41`UtBBXr;M@h-E@w0)7EpTt>`f6 zZ7MX_dq*_1h2Cl5Kg%9;zFEd-mXTuG5|lEOpe)*GrewdgxnZ<@WGdb^I(hzmc*4Pd|~s>m~%*08sb1WE=AaVjOo|x zd1e?ihVD0cl}Y5F87^?sjf(wx>q%>1rF&3Z|paq zc2xr!$`napTfYO%bJslgDQ1v=(y@TYqEFLB{Vfrt)nl{l?Z09_j=tGzO)Dc|noIu^ zJ#7sdsiuaHO5cE;vHQvx8^&#BCo1?zsjUxaG7n3u->Qy7^=_CY|1vFyZu|{o9=?3{ zqN0ZWj)I{&XEJC*(hqXx|DPWZkvzq1rdE$9-^a61#>fGc+a4oR1a&itz~Nemw3)%Il--j_ zBHgUo|K)R+RX_hnbp3DR$1>;qq%=h2U6=lz(o$!6g1Or-qj9M}Ph2GO5N1JIZMIhA zEGW}A{b>ivZJje=pYy1fh0gD3IR6l@(rcQapCvwD?nn|ThVFLoFdrDGPpvIa>r{ct z+@B4Y{Y5#~{V0oA^;g6J>ni?n%PW^eO#2aURbFqB^@zG%??PMM7$czdRme@i4zJcn zvCU7JHv^;3T$ZG#By*Eaa5C$!dA;KTy95=Z2EAz9OMU-XvW60UlZK&;_}^IIWvb)8 zU^N)B;va&6bGWay`s*$FZ5k}}hL-^s0|NroIFi%mnrzne_YL`FUwW4(?!(7edd<`ldTc=EDBJkWZh7lMvgrg^mLdW7CVz(!9MX7(WGk# z9Ho5Xj2QR!litk-PAuWY;))Z_YOPpIKz4FRYR*y~Pe(}vy7$5L$=1-mA}W^ znm{^e6gOa!oRNfEs&IlGhNM?FbjhU|_soVOH68l-KIL7HP2~n+&Ov08>`Xk>GyBjM zp6iC&y;SJs0c_w_d*(14>gxiGO?qSpu$iec41I%;*8$q)rfS9~9hubaN?kwU?4gX_a<&>K66 z>)1aE3(BJ32`Pa#>bMOSQ1E?axZnBNtXmoVm%y0kU}tHY!=8<x9|_b`d0FFl5P#0EEJ|{`C_US5A&f( zQsM`GESZGRayfytmsfZdss#6i`q~QK&|DVzUP*+mn;w7w{fyu|Olt7{pilP*zVW7) zY{m)~D`UwB&~7fL+|C`dVXARMC+{1n2t(vwY|;P20Ga0A6S#0dIobmWA#u!zQC#vG z5)0cXzp^){8EDS0*XgIgPD9nHHoIo_t9;(K27b8^cxHT$Gp}2Kn)0BZOImbYFb7$G zpWSE#Cm0ypk{V1ln*R?3$fUp;rRrzknhb}(KuO6kdbc=`m;vEgDezsjgKfsg#;Sb< z3sXv3yft$|qek`j2ZDWXFh+)f+MG6g3;!1e%@g_|D~iAkdj9~ct&yGIKBxzt8KOh_ zM%C~?9tUBiU;#9^+UTpx?VhJwNhtnND(wV4_v_z#Pdc?2gcgq>+Q&~uc{HyFtzic z(B;Fk<3r)N7GG~6)ZBqc5E+lG8N|(JGd+}%Ne4bPnd$zPFjEBhD2paNLu~CPZMx9Z z9b7Hlt{=Qb&{?PNJ}f9#0-qRmOJPAAfL(l=U%&>OrmqZ%o;#J^RqlGkxJZq+OmiL0ZibBHn(HnFZKbUfrt0QqJ21N9U%+}+L_p`n(Z+d?qEf%xOY zMR(YqS24}e46|rIh|kMWKwiV13xcFjNRaxU^o3aZUNH4&d`SXhEHe_EJCfza#u)ih z6DB?V5G}Pzf>LO1l%bEHDD^Hoy-b3XH{1ARRhP;B02#=+_lQ=doD>F`)%om$ZveIB zP=(flN=+9Eue~X=Pq0xHOchT(?-jYwP)+FV6`~!ZVqW(mE`rX!GGw;n2GnsV54Wy+ zt9g1VLfUq5Sn-d;oQu#RyKFHyxdk=lKzpj;x`0kDxe7LUpz+sQBeL>l6JMl}yMh*w z#!hlml30NCV8$ALjX&s>?w%^@sJ6EVO`y(MFt7m zOa$!AwDWHmO~0fxi z#RXzI`aMv0wd(B6SYk?(nq+xcj>Bl_un|agUb|EaY?elCVM`o>z?Mg&Q!|iy%t^|< z@tkm(&Wm5w1-8Xu^5K*MOY>^qHPLpS$Whyd5&f{+=aWM&clsT48uXTTo z5K#Pc;G16g*;uu+y_Ob}ZSbE+)g>LYaU}&US%F<@Qpwn7mcb7M+{r9F7zVmxk z&M{_ZjU(mj9$8?hVr%SiEMw#$(_Z>0jVwaCVzt(vm%gX-k(p{ZCI3vNFj9lL%^vj< zW4H$zHJB0>u!QoCeTDtD20hiqvaL(MWdUmlkI5NM|IB>YA8y4hUaG75{dUnl$9iL4 z_F~KoQ*&N*bB&QV!o6T@(ZHl~(VMK`#7KiOF*eZCRY~ubXR6*&I2ps&e^SeZ$DfgU zw8+bm`iu^n{_%BY^eqj%mmsa`hgNSRuA2C#MpCk}yJv*aB9Z%ZhN~zhZ?7{BZ^sAz zDV$><)xf&D0dgEnf8`N3e)u+3Vz)965C(kiE&P*Ibp?8M3$?6v(LV!56x9VMQHDVG zUz>{TQWFk#s?2L@X4RvczU>L3j7y7T8{&~#QQGB)MH3P(tMP5~yZ=}!!Mxi22$U2* z*>VrJ1-k(&DQSgwIxiACB}p1N{8MEBZ2|XC1{@fLJ2W2oMfN3#G@gS zX)lP+hKLSxZtdbt4eM>*=`SV1u7Z9t&j`+A3ZoYzy0Q`I?$P-O)Yv%+gy#C2`KnNY zqM1Fm7>8de@vncfqcn*Kjigs0aszqc^k~va)hC#gXH_-AV(@|%*+NXm zuAV0s^YWV{Ir{T?wx=M?(4&+A)a!yQ!*mpLKg-M0?#$4Q+kL7=kE-L7in#jj@8iG8 zhP&u*g6gD@_-M8B+Bh!(^nVBQhHw7G+kH0Kc>|$+2GH0VJtDU>%(O&QYJR5gGG#m}kA3^Q~sA_)uC?DQ&ps2S>BaS(KJh%bZmc=Fo2o3rLT zL}W&h!$K#Y8^YfC5mlDSzfkb%M*oKBWH}-TR-DIJ|JGAIi)uK+N~rM}LSLLj@EHX^ zSBRULIzb5}T>9gZwlu`AoS*V$%+l}h6*z@;1#qyHnG{r{Ao|9|+H`!A$f%5( zylKtUDA)jJt-)E%-TTu5nH3#CzHM>=(gcE(Ew49HkuL+s=~tma97$=`G0lSPDoZ4Hv z?&?qWHTkPQtaVOyM_$jk>JKN`V82Kr`XzLvtn)kn)bFnHpZiW3@U=qA{mgtc7*vRn z9vF|L)hSlFX);Vgq@}EjD-{n+ztViv%m4Y^HCdRY3*Y^JEH~)u|5(gMK=FSaj`2<9 zxzlG9EGyC@;5*tcMEX-YpFBB=S)&U`ijAj zU^ueHyD|IslHutv1}*GC`R;yDa)^=l + + + FreeRTOS.org uIP WEB server demo + + + +Task Stats | Run Time Stats | TCP Stats | Connections | FreeRTOS Homepage | IO | 37K jpg +

+


+

+

Run-time statistics

+Page will refresh every 2 seconds.

+

Task            Abs Time      % Time
****************************************
+%! run-time +
+
+ + + diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-fs/stats.shtml b/Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-fs/stats.shtml new file mode 100644 index 000000000..f54118606 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-fs/stats.shtml @@ -0,0 +1,47 @@ + + + + FreeRTOS.org uIP WEB server demo + + + +Task Stats | Run Time Stats | TCP Stats | Connections | FreeRTOS Homepage | IO | 37K jpg +

+


+

+

Network statistics

+ +
+IP           Packets received
+             Packets sent
+             Forwaded
+             Dropped
+IP errors    IP version/header length
+             IP length, high byte
+             IP length, low byte
+             IP fragments
+             Header checksum
+             Wrong protocol
+ICMP	     Packets received
+             Packets sent
+             Packets dropped
+             Type errors
+             Checksum errors
+TCP          Packets received
+             Packets sent
+             Packets dropped
+             Checksum errors
+             Data packets without ACKs
+             Resets
+             Retransmissionsa
+             Syn to closed port
+UDP          Packets dropped
+             Packets received
+             Packets sent
+             Packets chkerr
+	     No connection avaliable
+
%! net-stats
+
+
+ + diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-fs/tcp.shtml b/Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-fs/tcp.shtml new file mode 100644 index 000000000..23dcdcae3 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-fs/tcp.shtml @@ -0,0 +1,21 @@ + + + + FreeRTOS.org uIP WEB server demo + + + +Task Stats | Run Time Stats | TCP Stats | Connections | FreeRTOS Homepage | IO | 37K jpg +

+


+
+

Network connections

+

+ + +%! tcp-connections + + + + + diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-fsdata.c b/Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-fsdata.c new file mode 100644 index 000000000..47823d100 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/httpd-fsdata.c @@ -0,0 +1,3871 @@ +static const char data_404_html[] = { + /* /404.html */ + 0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xd, 0xa, 0x20, 0x20, + 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x77, 0x68, 0x69, 0x74, 0x65, + 0x22, 0x3e, 0xd, 0xa, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x63, + 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, 0xd, 0xa, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3c, 0x68, 0x31, 0x3e, 0x34, 0x30, + 0x34, 0x20, 0x2d, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x6e, + 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x3c, 0x2f, + 0x68, 0x31, 0x3e, 0xd, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3c, 0x68, 0x33, 0x3e, 0x47, 0x6f, 0x20, 0x3c, 0x61, + 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x22, 0x3e, + 0x68, 0x65, 0x72, 0x65, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x69, + 0x6e, 0x73, 0x74, 0x65, 0x61, 0x64, 0x2e, 0x3c, 0x2f, 0x68, + 0x33, 0x3e, 0xd, 0xa, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, + 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, 0xd, 0xa, 0x20, + 0x20, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xd, 0xa, + 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0}; + +static const char data_index_html[] = { + /* /index.html */ + 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, + 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, + 0x43, 0x20, 0x22, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f, + 0x2f, 0x44, 0x54, 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20, + 0x34, 0x2e, 0x30, 0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x45, + 0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, + 0x67, 0x2f, 0x54, 0x52, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x34, + 0x2f, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x2e, 0x64, 0x74, 0x64, + 0x22, 0x3e, 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, + 0xd, 0xa, 0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, + 0xd, 0xa, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x74, + 0x6c, 0x65, 0x3e, 0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, + 0x53, 0x2e, 0x6f, 0x72, 0x67, 0x20, 0x75, 0x49, 0x50, 0x20, + 0x57, 0x45, 0x42, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x20, 0x64, 0x65, 0x6d, 0x6f, 0x3c, 0x2f, 0x74, 0x69, 0x74, + 0x6c, 0x65, 0x3e, 0xd, 0xa, 0x20, 0x20, 0x3c, 0x2f, 0x68, + 0x65, 0x61, 0x64, 0x3e, 0xd, 0xa, 0x20, 0x20, 0x3c, 0x42, + 0x4f, 0x44, 0x59, 0x20, 0x6f, 0x6e, 0x4c, 0x6f, 0x61, 0x64, + 0x3d, 0x22, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x73, + 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x28, + 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x6c, 0x6f, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x68, 0x72, 0x65, 0x66, 0x3d, + 0x27, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x73, 0x68, 0x74, + 0x6d, 0x6c, 0x27, 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x2c, + 0x31, 0x30, 0x30, 0x29, 0x22, 0x3e, 0xd, 0xa, 0x3c, 0x66, + 0x6f, 0x6e, 0x74, 0x20, 0x66, 0x61, 0x63, 0x65, 0x3d, 0x22, + 0x61, 0x72, 0x69, 0x61, 0x6c, 0x22, 0x3e, 0xd, 0xa, 0x4c, + 0x6f, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x6e, 0x64, + 0x65, 0x78, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x2e, 0x20, + 0x20, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x20, 0x3c, 0x61, 0x20, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x68, + 0x65, 0x72, 0x65, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x69, 0x66, + 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x6d, + 0x61, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x72, + 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x65, 0x64, 0x2e, + 0xd, 0xa, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0xd, + 0xa, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0xd, 0xa, + 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xd, 0xa, 0x3c, + 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xd, 0xa, 0xd, 0xa, +0}; + +static const char data_index_shtml[] = { + /* /index.shtml */ + 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, + 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, + 0x43, 0x20, 0x22, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f, + 0x2f, 0x44, 0x54, 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20, + 0x34, 0x2e, 0x30, 0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x45, + 0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, + 0x67, 0x2f, 0x54, 0x52, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x34, + 0x2f, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x2e, 0x64, 0x74, 0x64, + 0x22, 0x3e, 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, + 0xd, 0xa, 0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, + 0xd, 0xa, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x74, + 0x6c, 0x65, 0x3e, 0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, + 0x53, 0x2e, 0x6f, 0x72, 0x67, 0x20, 0x75, 0x49, 0x50, 0x20, + 0x57, 0x45, 0x42, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x20, 0x64, 0x65, 0x6d, 0x6f, 0x3c, 0x2f, 0x74, 0x69, 0x74, + 0x6c, 0x65, 0x3e, 0xd, 0xa, 0x20, 0x20, 0x3c, 0x2f, 0x68, + 0x65, 0x61, 0x64, 0x3e, 0xd, 0xa, 0x20, 0x20, 0x3c, 0x42, + 0x4f, 0x44, 0x59, 0x20, 0x6f, 0x6e, 0x4c, 0x6f, 0x61, 0x64, + 0x3d, 0x22, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x73, + 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x28, + 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x6c, 0x6f, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x68, 0x72, 0x65, 0x66, 0x3d, + 0x27, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x73, 0x68, 0x74, + 0x6d, 0x6c, 0x27, 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x2c, + 0x32, 0x30, 0x30, 0x30, 0x29, 0x22, 0x3e, 0xd, 0xa, 0x3c, + 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x66, 0x61, 0x63, 0x65, 0x3d, + 0x22, 0x61, 0x72, 0x69, 0x61, 0x6c, 0x22, 0x3e, 0xd, 0xa, + 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, + 0x22, 0x3e, 0x54, 0x61, 0x73, 0x6b, 0x20, 0x53, 0x74, 0x61, + 0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, + 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, + 0x72, 0x65, 0x66, 0x3d, 0x22, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, + 0x52, 0x75, 0x6e, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x20, 0x53, + 0x74, 0x61, 0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, + 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, + 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x73, 0x74, 0x61, + 0x74, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, + 0x54, 0x43, 0x50, 0x20, 0x53, 0x74, 0x61, 0x74, 0x73, 0x3c, + 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, + 0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, + 0x3d, 0x22, 0x74, 0x63, 0x70, 0x2e, 0x73, 0x68, 0x74, 0x6d, + 0x6c, 0x22, 0x3e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, + 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, + 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x66, 0x72, + 0x65, 0x65, 0x72, 0x74, 0x6f, 0x73, 0x2e, 0x6f, 0x72, 0x67, + 0x2f, 0x22, 0x3e, 0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, + 0x53, 0x20, 0x48, 0x6f, 0x6d, 0x65, 0x70, 0x61, 0x67, 0x65, + 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, + 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, + 0x66, 0x3d, 0x22, 0x69, 0x6f, 0x2e, 0x73, 0x68, 0x74, 0x6d, + 0x6c, 0x22, 0x3e, 0x49, 0x4f, 0x3c, 0x2f, 0x61, 0x3e, 0x20, + 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, + 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x6c, 0x6f, + 0x67, 0x6f, 0x2e, 0x6a, 0x70, 0x67, 0x22, 0x3e, 0x33, 0x37, + 0x4b, 0x20, 0x6a, 0x70, 0x67, 0x3c, 0x2f, 0x61, 0x3e, 0xd, + 0xa, 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x70, 0x3e, 0xd, 0xa, + 0x3c, 0x68, 0x72, 0x3e, 0xd, 0xa, 0x3c, 0x62, 0x72, 0x3e, + 0x3c, 0x70, 0x3e, 0xd, 0xa, 0x3c, 0x68, 0x32, 0x3e, 0x54, + 0x61, 0x73, 0x6b, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x73, + 0x74, 0x69, 0x63, 0x73, 0x3c, 0x2f, 0x68, 0x32, 0x3e, 0xd, + 0xa, 0x50, 0x61, 0x67, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, + 0x20, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x20, 0x65, + 0x76, 0x65, 0x72, 0x79, 0x20, 0x32, 0x20, 0x73, 0x65, 0x63, + 0x6f, 0x6e, 0x64, 0x73, 0x2e, 0x3c, 0x70, 0x3e, 0xd, 0xa, + 0x3c, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x66, 0x61, 0x63, 0x65, + 0x3d, 0x22, 0x63, 0x6f, 0x75, 0x72, 0x69, 0x65, 0x72, 0x22, + 0x3e, 0x3c, 0x70, 0x72, 0x65, 0x3e, 0x54, 0x61, 0x73, 0x6b, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x20, 0x20, 0x50, 0x72, 0x69, + 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x20, 0x53, 0x74, 0x61, + 0x63, 0x6b, 0x9, 0x23, 0x3c, 0x62, 0x72, 0x3e, 0x2a, 0x2a, + 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, + 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, + 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, + 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, + 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x3c, 0x62, 0x72, 0x3e, + 0xd, 0xa, 0x25, 0x21, 0x20, 0x72, 0x74, 0x6f, 0x73, 0x2d, + 0x73, 0x74, 0x61, 0x74, 0x73, 0xd, 0xa, 0x3c, 0x2f, 0x70, + 0x72, 0x65, 0x3e, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, + 0xd, 0xa, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0xd, + 0xa, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xd, 0xa, + 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xd, 0xa, 0xd, + 0xa, 0}; + +static const char data_io_shtml[] = { + /* /io.shtml */ + 0x2f, 0x69, 0x6f, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, + 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, + 0x43, 0x20, 0x22, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f, + 0x2f, 0x44, 0x54, 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20, + 0x34, 0x2e, 0x30, 0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x45, + 0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, + 0x67, 0x2f, 0x54, 0x52, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x34, + 0x2f, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x2e, 0x64, 0x74, 0x64, + 0x22, 0x3e, 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, + 0xd, 0xa, 0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, + 0xd, 0xa, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x74, + 0x6c, 0x65, 0x3e, 0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, + 0x53, 0x2e, 0x6f, 0x72, 0x67, 0x20, 0x75, 0x49, 0x50, 0x20, + 0x57, 0x45, 0x42, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x20, 0x64, 0x65, 0x6d, 0x6f, 0x3c, 0x2f, 0x74, 0x69, 0x74, + 0x6c, 0x65, 0x3e, 0xd, 0xa, 0x20, 0x20, 0x3c, 0x2f, 0x68, + 0x65, 0x61, 0x64, 0x3e, 0xd, 0xa, 0x20, 0x20, 0x3c, 0x42, + 0x4f, 0x44, 0x59, 0x3e, 0xd, 0xa, 0x3c, 0x66, 0x6f, 0x6e, + 0x74, 0x20, 0x66, 0x61, 0x63, 0x65, 0x3d, 0x22, 0x61, 0x72, + 0x69, 0x61, 0x6c, 0x22, 0x3e, 0xd, 0xa, 0x3c, 0x61, 0x20, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x54, + 0x61, 0x73, 0x6b, 0x20, 0x53, 0x74, 0x61, 0x74, 0x73, 0x3c, + 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, + 0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, + 0x3d, 0x22, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x52, 0x75, 0x6e, + 0x20, 0x54, 0x69, 0x6d, 0x65, 0x20, 0x53, 0x74, 0x61, 0x74, + 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, + 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, + 0x65, 0x66, 0x3d, 0x22, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, + 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x54, 0x43, 0x50, + 0x20, 0x53, 0x74, 0x61, 0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, + 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, + 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x74, + 0x63, 0x70, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, + 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, + 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, + 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x66, 0x72, 0x65, 0x65, 0x72, + 0x74, 0x6f, 0x73, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x22, 0x3e, + 0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, 0x53, 0x20, 0x48, + 0x6f, 0x6d, 0x65, 0x70, 0x61, 0x67, 0x65, 0x3c, 0x2f, 0x61, + 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, + 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, + 0x69, 0x6f, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, + 0x49, 0x4f, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, + 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, + 0x72, 0x65, 0x66, 0x3d, 0x22, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, + 0x6a, 0x70, 0x67, 0x22, 0x3e, 0x33, 0x37, 0x4b, 0x20, 0x6a, + 0x70, 0x67, 0x3c, 0x2f, 0x61, 0x3e, 0xd, 0xa, 0x3c, 0x62, + 0x72, 0x3e, 0x3c, 0x70, 0x3e, 0xd, 0xa, 0x3c, 0x68, 0x72, + 0x3e, 0xd, 0xa, 0x3c, 0x62, 0x3e, 0x4c, 0x45, 0x44, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x4c, 0x43, 0x44, 0x20, 0x49, 0x4f, + 0x3c, 0x2f, 0x62, 0x3e, 0x3c, 0x62, 0x72, 0x3e, 0xd, 0xa, + 0xd, 0xa, 0x3c, 0x70, 0x3e, 0xd, 0xa, 0xd, 0xa, 0x55, + 0x73, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x68, 0x65, + 0x63, 0x6b, 0x20, 0x62, 0x6f, 0x78, 0x20, 0x74, 0x6f, 0x20, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x6e, 0x20, 0x6f, 0x72, + 0x20, 0x6f, 0x66, 0x66, 0x20, 0x4c, 0x45, 0x44, 0x20, 0x34, + 0x2c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x63, 0x6c, 0x69, + 0x63, 0x6b, 0x20, 0x22, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x20, 0x49, 0x4f, 0x22, 0x2e, 0xd, 0xa, 0xd, 0xa, 0xd, + 0xa, 0x3c, 0x70, 0x3e, 0xd, 0xa, 0x3c, 0x66, 0x6f, 0x72, + 0x6d, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x61, 0x46, + 0x6f, 0x72, 0x6d, 0x22, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x3d, 0x22, 0x2f, 0x69, 0x6f, 0x2e, 0x73, 0x68, 0x74, + 0x6d, 0x6c, 0x22, 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, + 0x3d, 0x22, 0x67, 0x65, 0x74, 0x22, 0x3e, 0xd, 0xa, 0x25, + 0x21, 0x20, 0x6c, 0x65, 0x64, 0x2d, 0x69, 0x6f, 0xd, 0xa, + 0x3c, 0x70, 0x3e, 0xd, 0xa, 0x3c, 0x69, 0x6e, 0x70, 0x75, + 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x73, 0x75, + 0x62, 0x6d, 0x69, 0x74, 0x22, 0x20, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3d, 0x22, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, + 0x49, 0x4f, 0x22, 0x3e, 0xd, 0xa, 0x3c, 0x2f, 0x66, 0x6f, + 0x72, 0x6d, 0x3e, 0xd, 0xa, 0x3c, 0x62, 0x72, 0x3e, 0x3c, + 0x70, 0x3e, 0xd, 0xa, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, + 0x3e, 0xd, 0xa, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, + 0xd, 0xa, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xd, + 0xa, 0xd, 0xa, 0}; + +static const char data_logo_jpg[] = { + /* /logo.jpg */ + 0x2f, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x6a, 0x70, 0x67, 0, + 0xff, 0xd8, 0xff, 0xe0, 00, 0x10, 0x4a, 0x46, 0x49, 0x46, + 00, 0x1, 0x1, 00, 00, 0x1, 00, 0x1, 00, 00, + 0xff, 0xdb, 00, 0x43, 00, 0x3, 0x2, 0x2, 0x3, 0x2, + 0x2, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, 0x4, 0x5, + 0x8, 0x5, 0x5, 0x4, 0x4, 0x5, 0xa, 0x7, 0x7, 0x6, + 0x8, 0xc, 0xa, 0xc, 0xc, 0xb, 0xa, 0xb, 0xb, 0xd, + 0xe, 0x12, 0x10, 0xd, 0xe, 0x11, 0xe, 0xb, 0xb, 0x10, + 0x16, 0x10, 0x11, 0x13, 0x14, 0x15, 0x15, 0x15, 0xc, 0xf, + 0x17, 0x18, 0x16, 0x14, 0x18, 0x12, 0x14, 0x15, 0x14, 0xff, + 0xdb, 00, 0x43, 0x1, 0x3, 0x4, 0x4, 0x5, 0x4, 0x5, + 0x9, 0x5, 0x5, 0x9, 0x14, 0xd, 0xb, 0xd, 0x14, 0x14, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0xff, 0xc0, + 00, 0x11, 0x8, 0x1, 0x8, 0x2, 0xc2, 0x3, 0x1, 0x22, + 00, 0x2, 0x11, 0x1, 0x3, 0x11, 0x1, 0xff, 0xc4, 00, + 0x1f, 00, 00, 0x1, 0x5, 0x1, 0x1, 0x1, 0x1, 0x1, + 0x1, 00, 00, 00, 00, 00, 00, 00, 00, 0x1, + 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, + 0xff, 0xc4, 00, 0xb5, 0x10, 00, 0x2, 0x1, 0x3, 0x3, + 0x2, 0x4, 0x3, 0x5, 0x5, 0x4, 0x4, 00, 00, 0x1, + 0x7d, 0x1, 0x2, 0x3, 00, 0x4, 0x11, 0x5, 0x12, 0x21, + 0x31, 0x41, 0x6, 0x13, 0x51, 0x61, 0x7, 0x22, 0x71, 0x14, + 0x32, 0x81, 0x91, 0xa1, 0x8, 0x23, 0x42, 0xb1, 0xc1, 0x15, + 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x9, 0xa, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, + 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, + 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, + 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, + 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, + 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, + 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, + 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, + 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xff, 0xc4, 00, 0x1f, 0x1, 00, 0x3, + 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 00, + 00, 00, 00, 00, 00, 0x1, 0x2, 0x3, 0x4, 0x5, + 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xff, 0xc4, 00, 0xb5, + 0x11, 00, 0x2, 0x1, 0x2, 0x4, 0x4, 0x3, 0x4, 0x7, + 0x5, 0x4, 0x4, 00, 0x1, 0x2, 0x77, 00, 0x1, 0x2, + 0x3, 0x11, 0x4, 0x5, 0x21, 0x31, 0x6, 0x12, 0x41, 0x51, + 0x7, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x8, 0x14, 0x42, + 0x91, 0xa1, 0xb1, 0xc1, 0x9, 0x23, 0x33, 0x52, 0xf0, 0x15, + 0x62, 0x72, 0xd1, 0xa, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, + 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, + 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, + 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, + 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, + 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, + 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, + 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, + 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, + 0xda, 00, 0xc, 0x3, 0x1, 00, 0x2, 0x11, 0x3, 0x11, + 00, 0x3f, 00, 0xfd, 0x53, 0xa2, 0x8a, 0x28, 00, 0xa2, + 0x8a, 0x28, 00, 0xa2, 0x8a, 0x28, 00, 0xa2, 0x8a, 0x28, + 00, 0xaa, 0xf7, 0xfa, 0x85, 0xb6, 0x95, 0x67, 0x2d, 0xd5, + 0xe4, 0xf1, 0xdb, 0x5b, 0x44, 0xa5, 0x9e, 0x59, 0x58, 0x2a, + 0xa8, 0x1e, 0xf5, 0xc6, 0x7c, 0x4e, 0xf8, 0xb3, 0xa6, 0xfc, + 0x39, 0xb4, 0x48, 0xb0, 0xb7, 0xda, 0xd5, 0xc6, 0x5, 0xb6, + 0x9e, 0x8d, 0x86, 0x72, 0x4e, 0x37, 0x37, 0xf7, 0x57, 0xf9, + 0xf6, 0xaa, 0x16, 0x5f, 0xd, 0x9f, 0xc6, 0xd0, 0xc5, 0xa9, + 0xf8, 0xc6, 0xe1, 0xef, 0xa6, 0x99, 0x3, 0xa6, 0x9e, 0x84, + 0xad, 0xbd, 0xb6, 0x7b, 0x2a, 0xf7, 0x3e, 0xe7, 0x9a, 0xe0, + 0xa9, 0x89, 0xbc, 0xdd, 0x1a, 0xb, 0x9a, 0x6b, 0x7e, 0xcb, + 0xd5, 0xfe, 0x9b, 0x9c, 0xb2, 0xaf, 0x79, 0x3a, 0x74, 0xb5, + 0x92, 0xdf, 0xb2, 0xf5, 0xff, 00, 0x23, 0x93, 0xf1, 0xa7, + 0xed, 0x5f, 0xa1, 0x69, 0x1b, 0xa1, 0xd0, 0x2d, 0x64, 0xd6, + 0x2e, 0x1, 0xc7, 0x9b, 0x26, 0x62, 0x84, 0x7d, 0xf, 0x53, + 0xf9, 0x57, 0x91, 0x6b, 0x5f, 0xb5, 0xf, 0x8e, 0x35, 0x49, + 0x9, 0xb7, 0xba, 0xb7, 0xd3, 0x23, 0xec, 0x96, 0xd0, 0x29, + 0xfd, 0x5b, 0x26, 0xbe, 0x92, 0x7f, 0x81, 0x1e, 0xb, 0x7f, + 0xf9, 0x84, 0x46, 0x3e, 0x95, 0xb, 0xfe, 0xcf, 0xfe, 0xa, + 0x93, 0xae, 0x96, 0xa3, 0xe8, 0x6b, 0xc2, 0xaf, 0x84, 0xcd, + 0xab, 0xbb, 0xba, 0xa9, 0x2e, 0xc9, 0xb5, 0xfa, 0x5c, 0xf0, + 0xb1, 0x18, 0x4c, 0xce, 0xbb, 0xd2, 0xb2, 0x8a, 0xec, 0xb4, + 0xff, 00, 0x82, 0x7c, 0x91, 0x3f, 0xc6, 0xf, 0x19, 0x5c, + 0x48, 0x5d, 0xfc, 0x45, 0x7e, 0x58, 0xf5, 0xc4, 0xb8, 0x1f, + 0x90, 0xa7, 0x27, 0xc6, 0x5f, 0x1a, 0x46, 0xca, 0x57, 0xc4, + 0x57, 0xc0, 0xaf, 0x23, 0xf7, 0x99, 0xfe, 0x95, 0xf5, 0x73, + 0xfe, 0xce, 0x9e, 0x9, 0x7f, 0xf9, 0x87, 0x15, 0xfa, 0x35, + 0x43, 0x27, 0xec, 0xd7, 0xe0, 0xa7, 0xe9, 0x67, 0x2a, 0xfd, + 0x1e, 0xbc, 0xcf, 0xec, 0x7c, 0xc5, 0x3b, 0xa9, 0xff, 00, + 0xe4, 0xcc, 0xf3, 0x3f, 0xb1, 0xf3, 0x1d, 0xd5, 0x6f, 0xc5, + 0x9f, 0x31, 0x2f, 0xc7, 0x9f, 0x1e, 0x29, 0xcf, 0xfc, 0x24, + 0x77, 0x47, 0xea, 0x10, 0xff, 00, 0x4a, 0x9e, 0x2f, 0xda, + 0x17, 0xc7, 0xd1, 0xc, 0xf, 0x10, 0xcc, 0x7b, 0xfc, 0xd0, + 0xc6, 0x7f, 0x9a, 0xd7, 0xd1, 0xed, 0xfb, 0x31, 0xf8, 0x34, + 0xe7, 0x10, 0xce, 0x7, 0xfb, 0xff, 00, 0xfd, 0x6a, 0x81, + 0xff, 00, 0x65, 0xcf, 0x8, 0x37, 0x4f, 0xb4, 0x83, 0xfe, + 0xf0, 0xa7, 0xfd, 0x99, 0x9a, 0xad, 0xaa, 0x7f, 0xe4, 0xcc, + 0x3f, 0xb2, 0xf3, 0x45, 0xb5, 0x6f, 0xc5, 0x9f, 0x3d, 0xff, + 00, 0xc3, 0x46, 0x7c, 0x40, 0xff, 00, 0xa0, 0xfb, 0xff, + 00, 0xe0, 0x3c, 0x5f, 0xfc, 0x4d, 0x48, 0xbf, 0xb4, 0x8f, + 0x8f, 0xd4, 0xe7, 0xfb, 0x6f, 0x3e, 0xc6, 0xda, 0x2f, 0xfe, + 0x26, 0xbd, 0xe9, 0xff, 00, 0x65, 0x6f, 0x9, 0xb6, 0x71, + 0x25, 0xd0, 0xff, 00, 0x81, 0xa, 0x85, 0xff, 00, 0x64, + 0xff, 00, 0xb, 0x30, 0xe2, 0xe6, 0xed, 0x4f, 0xd4, 0x51, + 0xfd, 0x9d, 0x9b, 0x2f, 0xb6, 0xff, 00, 0xf0, 0x26, 0x1f, + 0xd9, 0xd9, 0xb2, 0xda, 0xb7, 0xfe, 0x4c, 0xcf, 0x11, 0x5f, + 0xda, 0x63, 0xc7, 0xca, 0x79, 0xd5, 0xa3, 0x6f, 0x63, 0x6b, + 0x1f, 0xf8, 0x54, 0xcb, 0xfb, 0x50, 0x78, 0xf1, 0x40, 0x1f, + 0x6f, 0xb6, 0x3e, 0xe6, 0xd5, 0x2b, 0xd8, 0x5b, 0xf6, 0x49, + 0xf0, 0xd1, 0xe9, 0x7f, 0x76, 0xbe, 0xdc, 0x54, 0xf, 0xfb, + 0x22, 0xe8, 0x24, 0x7c, 0xba, 0xa5, 0xd0, 0x3f, 0xee, 0x8a, + 0x5f, 0x52, 0xce, 0x17, 0xda, 0x7f, 0xf8, 0x17, 0xfc, 0x10, + 0xfa, 0x8e, 0x70, 0xbf, 0xe5, 0xef, 0xfe, 0x4c, 0x79, 0x7a, + 0xfe, 0xd5, 0x9e, 0x38, 0x4, 0x66, 0x4d, 0x3d, 0xb1, 0xd8, + 0xda, 0xf5, 0xfd, 0x6a, 0x55, 0xfd, 0xac, 0x7c, 0x6a, 0xbd, + 0x53, 0x4c, 0x6f, 0xad, 0xb3, 0x7f, 0xf1, 0x55, 0xe8, 0xcf, + 0xfb, 0x21, 0x68, 0xe7, 0xee, 0xea, 0xd7, 0x3, 0xea, 0xa2, + 0xa0, 0x7f, 0xd9, 0x3, 0x4e, 0x39, 0xdb, 0xac, 0x4c, 0x3e, + 0xa8, 0x29, 0xfd, 0x5b, 0x39, 0x5f, 0x69, 0xff, 00, 0xe0, + 0x48, 0x3e, 0xa9, 0x9d, 0x2f, 0xf9, 0x79, 0xf8, 0x9c, 0x18, + 0xfd, 0xad, 0x3c, 0x67, 0xff, 00, 0x3c, 0x74, 0xbf, 0xfc, + 0x7, 0x6f, 0xfe, 0x2e, 0x9e, 0x3f, 0x6b, 0x6f, 0x18, 0x77, + 0xb6, 0xd2, 0xcf, 0xfd, 0xb0, 0x7f, 0xfe, 0x2e, 0xbb, 0x37, + 0xfd, 0x8f, 0xac, 0xff, 00, 0x87, 0x5a, 0x93, 0xf1, 0x41, + 0x50, 0xbf, 0xec, 0x7b, 0x11, 0xfb, 0xba, 0xe3, 0xf, 0xac, + 0x74, 0x7b, 0x1c, 0xe9, 0x75, 0x7f, 0x7a, 0x17, 0xd5, 0xf3, + 0xb5, 0xf6, 0xff, 00, 0x14, 0x72, 0xc9, 0xfb, 0x5d, 0x78, + 0xb1, 0x4f, 0xcd, 0x63, 0xa5, 0xb0, 0xf4, 0xf2, 0x9c, 0x7f, + 0xec, 0xd5, 0x62, 0x2f, 0xda, 0xff, 00, 0xc4, 0x8a, 0xb8, + 0x7d, 0x27, 0x4d, 0x73, 0xea, 0x3, 0x8f, 0xfd, 0x9a, 0xb6, + 0x9f, 0xf6, 0x3d, 0x71, 0x8d, 0x9a, 0xd8, 0x3f, 0x58, 0xea, + 0x17, 0xfd, 0x8f, 0xee, 0x81, 0x3b, 0x75, 0x98, 0xcf, 0xa6, + 0x52, 0xa7, 0x93, 0x3a, 0x5f, 0xcd, 0xf7, 0xa0, 0xf6, 0x79, + 0xe2, 0xfb, 0x5f, 0x91, 0x4d, 0x7f, 0x6c, 0x4d, 0x6c, 0x1, + 0xbb, 0x42, 0xb0, 0x27, 0xb9, 0xe, 0xe3, 0x35, 0x3a, 0x7e, + 0xd8, 0xda, 0x98, 0x3f, 0x37, 0x87, 0x6d, 0x8, 0xf6, 0xb8, + 0x61, 0xfd, 0x29, 0xad, 0xfb, 0x21, 0x6a, 0x40, 0x71, 0xaa, + 0xc2, 0x4f, 0xa6, 0xda, 0x85, 0xff, 00, 0x64, 0x4d, 0x60, + 0x1f, 0x97, 0x53, 0x80, 0xfe, 0x14, 0xef, 0x9d, 0xae, 0xff, + 00, 0x80, 0x7f, 0xc2, 0xe2, 0xeb, 0xf9, 0x17, 0x7, 0xed, + 0x8f, 0x7b, 0xdf, 0xc3, 0x56, 0xdf, 0x85, 0xd3, 0x7f, 0xf1, + 0x35, 0x22, 0xfe, 0xd8, 0xf7, 0x3c, 0x6e, 0xf0, 0xd4, 0x3e, + 0xf8, 0xba, 0x3f, 0xfc, 0x4d, 0x64, 0x37, 0xec, 0x8f, 0xaf, + 0x1, 0xf2, 0xdf, 0xdb, 0x93, 0xe8, 0x6a, 0x16, 0xfd, 0x92, + 0xfc, 0x48, 0xf, 0xcb, 0x75, 0x6c, 0x47, 0xae, 0xea, 0x4e, + 0xae, 0x74, 0xbf, 0x9b, 0xee, 0x42, 0xe7, 0xcf, 0x17, 0xfc, + 0x32, 0x3a, 0x45, 0xfd, 0xb1, 0xf9, 0xf9, 0xbc, 0x32, 0x31, + 0xed, 0x77, 0xff, 00, 0xd8, 0xd4, 0xf1, 0xfe, 0xd8, 0xf6, + 0xd8, 0x3b, 0xfc, 0x37, 0x26, 0x7b, 0x6d, 0xba, 0x1f, 0xfc, + 0x4d, 0x71, 0x6f, 0xfb, 0x29, 0x78, 0xa9, 0x46, 0x43, 0xdb, + 0x93, 0xe9, 0xbc, 0x54, 0x2f, 0xfb, 0x2c, 0x78, 0xb5, 0x71, + 0x81, 0x9, 0xfa, 0x38, 0xa5, 0xf5, 0x9c, 0xe5, 0x74, 0x97, + 0xfe, 0x2, 0xbf, 0xc8, 0x7e, 0xdf, 0x3b, 0x5f, 0x67, 0xf0, + 0x47, 0xa2, 0x45, 0xfb, 0x62, 0xe9, 0x45, 0x7, 0x99, 0xe1, + 0xeb, 0xb0, 0xfe, 0x8b, 0x3a, 0x11, 0xfc, 0xaa, 0xc2, 0x7e, + 0xd8, 0x3a, 0x1, 0xc6, 0xfd, 0xf, 0x50, 0x5f, 0x5c, 0x3a, + 0x1f, 0xeb, 0x5e, 0x58, 0xff, 00, 0xb2, 0xff, 00, 0x8c, + 0x57, 0x38, 0x82, 0x26, 0xc7, 0xfb, 0x62, 0xa2, 0x6f, 0xd9, + 0x97, 0xc6, 0x63, 0x18, 0xb4, 0x43, 0xf4, 0x71, 0x4f, 0xeb, + 0xb9, 0xc2, 0xfb, 0x2f, 0xff, 00, 0x1, 0xff, 00, 0x80, + 0x1f, 0x5a, 0xce, 0x97, 0xd8, 0xfc, 0x11, 0xeb, 0xa3, 0xf6, + 0xbe, 0xf0, 0xd7, 0x7d, 0x23, 0x53, 0x1f, 0xf7, 0xef, 0xff, + 00, 0x8a, 0xa7, 0xaf, 0xed, 0x79, 0xe1, 0x72, 0x39, 0xd2, + 0xf5, 0x31, 0xff, 00, 0x1, 0x4f, 0xfe, 0x2a, 0xbc, 0x61, + 0xff, 00, 0x66, 0xcf, 0x1a, 0xa6, 0x71, 0xa7, 0x86, 0xc7, + 0xa3, 0x8a, 0x85, 0xff, 00, 0x67, 0x5f, 0x1b, 0xa0, 0xcf, + 0xf6, 0x53, 0x1f, 0xa3, 0xa, 0x3f, 0xb4, 0x33, 0x65, 0xf6, + 0x5f, 0xfe, 0x3, 0xff, 00, 00, 0x5f, 0x5e, 0xce, 0x56, + 0xf4, 0xff, 00, 0x3, 0xdc, 0x47, 0xed, 0x71, 0xe1, 0x42, + 0x46, 0x74, 0xfd, 0x4c, 0xf, 0xf7, 0x13, 0xff, 00, 0x8a, + 0xa9, 0xe3, 0xfd, 0xac, 0xfc, 0x1e, 0xc4, 0xee, 0xb6, 0xd4, + 0x90, 0x7f, 0xd7, 0x15, 0x3f, 0xfb, 0x35, 0x78, 0x3, 0x7e, + 0xcf, 0xfe, 0x36, 0x52, 0x47, 0xf6, 0x3c, 0x9f, 0x81, 0x15, + 0xb, 0xfc, 0x9, 0xf1, 0xa2, 0xc, 0xff, 00, 0x63, 0x4c, + 0x7e, 0x98, 0xa5, 0xfd, 0xa7, 0x9a, 0x2d, 0xe2, 0xff, 00, + 0xf0, 0x16, 0x1f, 0xda, 0x39, 0xba, 0xde, 0x9f, 0xe0, 0x7d, + 0x19, 0x1f, 0xed, 0x59, 0xe0, 0x97, 0x5c, 0xb7, 0xf6, 0x8a, + 0x1f, 0x43, 0x6c, 0xf, 0xfe, 0xcd, 0x53, 0xaf, 0xed, 0x4b, + 0xe0, 0x43, 0x8c, 0xdc, 0x5e, 0x8f, 0xad, 0xab, 0x71, 0x5f, + 0x33, 0xb7, 0xc1, 0x2f, 0x19, 0x29, 0xff, 00, 0x90, 0x2d, + 0xc7, 0xe5, 0x50, 0x37, 0xc1, 0xcf, 0x18, 0x20, 0xc9, 0xd1, + 0x2e, 0x71, 0xec, 0xb5, 0x5f, 0xda, 0xf9, 0x92, 0xde, 0x1f, + 0xf9, 0x2b, 0xf, 0xed, 0x5c, 0xd5, 0x6f, 0x4b, 0xf0, 0x7f, + 0xe6, 0x7d, 0x48, 0x3f, 0x69, 0xff, 00, 0x1, 0x1f, 0xf9, + 0x7f, 0xba, 0x1f, 0xf6, 0xe8, 0xff, 00, 0xe1, 0x4e, 0x1f, + 0xb4, 0xe7, 0x80, 0x4f, 0xfc, 0xc4, 0x6e, 0x7, 0xd6, 0xd1, + 0xff, 00, 0xc2, 0xbe, 0x54, 0x7f, 0x84, 0xde, 0x2d, 0x8f, + 0xae, 0x87, 0x77, 0xf8, 0x25, 0x40, 0xdf, 0xc, 0xfc, 0x50, + 0xa0, 0x93, 0xa3, 0x5d, 0xf1, 0xff, 00, 0x4c, 0xcd, 0x27, + 0x9d, 0x66, 0xb, 0xec, 0x2f, 0xfc, 0x5, 0xff, 00, 0x98, + 0xbf, 0xb6, 0x33, 0x35, 0xbd, 0x2f, 0xc1, 0xff, 00, 0x99, + 0xf5, 0xa8, 0xfd, 0xa5, 0xfc, 0x2, 0x46, 0x7f, 0xb5, 0x26, + 0x1f, 0x5b, 0x57, 0xff, 00, 0xa, 0x9d, 0x3f, 0x68, 0xdf, + 00, 0xb9, 0xc7, 0xf6, 0xd1, 0x5f, 0x76, 0xb7, 0x93, 0xff, + 00, 0x89, 0xaf, 0x8f, 0x9b, 0xe1, 0xe7, 0x89, 0x13, 0x19, + 0xd2, 0x2e, 0xc6, 0x7f, 0xe9, 0x99, 0xa8, 0xdb, 0xc0, 0xbe, + 0x20, 0x4c, 0xe7, 0x4a, 0xbb, 0x18, 0xeb, 0xfb, 0xb3, 0x4b, + 0xfb, 0x73, 0x1c, 0xb7, 0x82, 0xfb, 0x9f, 0xf9, 0x87, 0xf6, + 0xd6, 0x60, 0xb7, 0xa5, 0xf8, 0x3f, 0xf3, 0x3e, 0xcc, 0x8f, + 0xf6, 0x84, 0xf0, 0xc, 0x99, 0xff, 00, 0x89, 0xfc, 0x6b, + 0x8f, 0xef, 0x43, 0x20, 0xff, 00, 0xd9, 0x6a, 0x75, 0xf8, + 0xf1, 0xe0, 0x26, 0x50, 0x47, 0x88, 0xed, 0xb9, 0xf5, 0x57, + 0x1f, 0xd2, 0xbe, 0x27, 0x6f, 0x7, 0x6b, 0x8b, 0xd7, 0x4c, + 0xba, 0x1f, 0xf6, 0xcc, 0xd4, 0x6d, 0xe1, 0x6d, 0x65, 0x9, + 0x7, 0x4e, 0xba, 0x18, 0xff, 00, 0xa6, 0x66, 0x9f, 0xf6, + 0xfe, 0x2d, 0x6f, 0x5, 0xf7, 0x3f, 0xf3, 0x1f, 0xf6, 0xee, + 0x35, 0x6f, 0x47, 0xf0, 0x67, 0xdc, 0x23, 0xe3, 0x87, 0x81, + 0xf, 0xfc, 0xcc, 0xd6, 0x5f, 0x99, 0xff, 00, 0xa, 0x92, + 0x3f, 0x8d, 0x3e, 0x7, 0x90, 0x90, 0xbe, 0x26, 0xb0, 0xe3, + 0xd6, 0x4c, 0x7f, 0x4a, 0xf8, 0x54, 0xe8, 0x1a, 0xa2, 0x8c, + 0x9b, 0x1b, 0x80, 0x3f, 0xeb, 0x99, 0xa6, 0x1d, 0x1b, 0x51, + 0x5e, 0xb6, 0x93, 0x8f, 0xf8, 0x1, 0xa7, 0xfe, 0xb0, 0xe2, + 0x7f, 0x92, 0x3f, 0x8f, 0xf9, 0x87, 0xf6, 0xfe, 0x2f, 0xad, + 0x1f, 0xcc, 0xfb, 0xc9, 0x7e, 0x2f, 0x78, 0x2d, 0x86, 0x47, + 0x89, 0x74, 0xec, 0x7f, 0xd7, 0x61, 0x53, 0x47, 0xf1, 0x4f, + 0xc2, 0x12, 0x90, 0x17, 0xc4, 0x7a, 0x71, 0x27, 0xa7, 0xfa, + 0x42, 0xd7, 0xc0, 0xa7, 0x4b, 0xbe, 0x1d, 0x6d, 0xa5, 0x1f, + 0xf0, 0x3, 0x4d, 0x3a, 0x7d, 0xe2, 0xf5, 0xb7, 0x97, 0xfe, + 0xf8, 0x34, 0x7f, 0xac, 0x55, 0xfa, 0xc2, 0x3f, 0x88, 0xff, + 00, 0xd6, 0x1c, 0x42, 0xde, 0x8f, 0xe6, 0x7e, 0x82, 0xc3, + 0xf1, 0xb, 0xc3, 0x17, 0xd, 0xb6, 0x3f, 0x10, 0x69, 0xac, + 0x7a, 0xe3, 0xed, 0x28, 0x3f, 0xad, 0x5a, 0x4f, 0x17, 0xe8, + 0x52, 0x2e, 0x53, 0x59, 0xb0, 0x61, 0xea, 0x2e, 0x50, 0xff, + 00, 0x5a, 0xfc, 0xee, 0x36, 0xb7, 0x23, 0xac, 0x2e, 0x3f, + 0xe0, 0x26, 0x9a, 0x61, 0x98, 0x7f, 0xcb, 0x36, 0xfc, 0xaa, + 0xd7, 0x12, 0x54, 0xeb, 0x4d, 0x7d, 0xe5, 0x2e, 0x23, 0xab, + 0xd6, 0x8f, 0xe3, 0xff, 00, 00, 0xfd, 0x1c, 0x1a, 0xee, + 0x9a, 0x71, 0x8d, 0x42, 0xd4, 0xe7, 0xfe, 0x9b, 0x2f, 0xf8, + 0xd3, 0x86, 0xb3, 0xa7, 0x9e, 0x97, 0xd6, 0xc7, 0xfe, 0xdb, + 0x2f, 0xf8, 0xd7, 0xe7, 0x6, 0xc9, 0x47, 0xf0, 0x37, 0xe5, + 0x47, 0xef, 0x57, 0xb3, 0xa, 0xd3, 0xfd, 0x64, 0x97, 0xfc, + 0xfa, 0x5f, 0x7f, 0xfc, 0x1, 0xff, 00, 0xac, 0x92, 0xff, + 00, 0x9f, 0x3f, 0x8f, 0xfc, 0x3, 0xf4, 0x84, 0x6a, 0xb6, + 0x47, 0xa5, 0xe4, 0x7, 0xe9, 0x2a, 0xff, 00, 0x8d, 0x38, + 0x6a, 0x16, 0xad, 0x8c, 0x5c, 0xc2, 0x73, 0xe9, 0x20, 0xaf, + 0xcd, 0xc1, 0x24, 0xc3, 0xa1, 0x61, 0xf9, 0xd3, 0x85, 0xcd, + 0xc2, 0xf4, 0x77, 0x18, 0xff, 00, 0x68, 0xd3, 0x5c, 0x48, + 0xff, 00, 0xe7, 0xd7, 0xe3, 0xff, 00, 00, 0x7f, 0xeb, + 0x2f, 0x7a, 0x5f, 0x8f, 0xfc, 0x3, 0xf4, 0x95, 0x67, 0x8d, + 0xce, 0x16, 0x44, 0x63, 0xe8, 0x18, 0x1a, 0x7e, 0x47, 0xad, + 0x7e, 0x6d, 0xae, 0xa7, 0x7a, 0x87, 0x2b, 0x73, 0x32, 0x9f, + 0x51, 0x21, 0x1f, 0xd6, 0xa4, 0x1a, 0xe6, 0xa2, 0xbd, 0x2f, + 0x6e, 0x47, 0xd2, 0x66, 0xff, 00, 0x1a, 0xa5, 0xc4, 0x9d, + 0xe9, 0x7e, 0x3f, 0xf0, 0xa, 0xff, 00, 0x59, 0x63, 0xff, + 00, 0x3e, 0xbf, 0x1f, 0xf8, 0x7, 0xe9, 0x6, 0x45, 0x19, + 0xaf, 0xce, 0x31, 0xe2, 0x4d, 0x58, 0xc, 0xd, 0x4a, 0xf0, + 0xf, 0x69, 0xdf, 0xfc, 0x69, 0xc3, 0xc5, 0x3a, 0xc8, 0x3c, + 0x6a, 0x97, 0xc0, 0xff, 00, 0xd7, 0xc3, 0xff, 00, 0x8d, + 0x5f, 0xfa, 0xc7, 0x1f, 0xf9, 0xf5, 0xf8, 0xff, 00, 0xc0, + 0x1f, 0xfa, 0xcb, 0x4f, 0xfe, 0x7d, 0x3f, 0xbf, 0xfe, 0x1, + 0xfa, 0x35, 0x9a, 0x5a, 0xfc, 0xe8, 0x5f, 0x18, 0xeb, 0xb1, + 0xe4, 0x2e, 0xb1, 0x7e, 0xb9, 0xeb, 0x8b, 0x97, 0xe7, 0xf5, + 0xa9, 0x53, 0xc7, 0x7e, 0x22, 0x89, 0x76, 0xae, 0xb9, 0xa9, + 0x28, 0xf4, 0x17, 0x6f, 0xfe, 0x34, 0x7f, 0xac, 0x71, 0xff, + 00, 0x9f, 0x5f, 0x8f, 0xfc, 0x2, 0x97, 0x12, 0xd2, 0xeb, + 0x4d, 0xfd, 0xe7, 0xe8, 0x95, 0x15, 0xf9, 0xe8, 0x9f, 0x12, + 0xbc, 0x55, 0x19, 0x5, 0x7c, 0x43, 0xaa, 0x2, 0x3a, 0x7f, + 0xa5, 0xbf, 0xf8, 0xd4, 0xf1, 0xfc, 0x57, 0xf1, 0x84, 0x59, + 0xdb, 0xe2, 0x5d, 0x50, 0x67, 0xfe, 0x9e, 0x9f, 0xfc, 0x6a, + 0xd7, 0x11, 0xd3, 0xeb, 0x4d, 0xfd, 0xe8, 0xb5, 0xc4, 0x94, + 0x3a, 0xc1, 0xfe, 0x7, 0xe8, 0x25, 0x15, 0xf0, 00, 0xf8, + 0xc3, 0xe3, 0x40, 0x38, 0xf1, 0x3e, 0xa9, 0xff, 00, 0x81, + 0xd, 0x4f, 0x1f, 0x19, 0xbc, 0x6c, 0xe, 0x7f, 0xe1, 0x26, + 0xd4, 0x7f, 0xef, 0xf1, 0xaa, 0xff, 00, 0x58, 0xa8, 0xff, + 00, 0xcf, 0xb7, 0xf8, 0xf, 0xfd, 0x64, 0xc3, 0xff, 00, + 0x23, 0xfc, 0xf, 0xbf, 0x28, 0xaf, 0x82, 0x57, 0xe3, 0x8f, + 0x8e, 0x54, 0xe4, 0x78, 0x92, 0xf8, 0xfd, 0x5c, 0x7f, 0x85, + 0x4a, 0x9f, 0x1e, 0x3c, 0x74, 0x99, 0xc7, 0x88, 0xae, 0xcf, + 0xd7, 0x7, 0xfa, 0x53, 0xff, 00, 0x58, 0xa8, 0x7f, 0xcf, + 0xb9, 0x7e, 0x1f, 0xe6, 0x5a, 0xe2, 0x3c, 0x2f, 0xf2, 0xbf, + 0xc3, 0xfc, 0xcf, 0xbc, 0x68, 0xaf, 0x86, 0x23, 0xfd, 0xa1, + 0xfc, 0x7b, 0x18, 0x51, 0xfd, 0xbd, 0x23, 0x6d, 0xfe, 0xf4, + 0x48, 0x73, 0xf5, 0xe2, 0xac, 0xc7, 0xfb, 0x4a, 0xf8, 0xf6, + 0x37, 0xdd, 0xfd, 0xae, 0x8d, 0xec, 0xd6, 0xd1, 0x91, 0xfc, + 0xaa, 0xd7, 0x10, 0xe1, 0xba, 0xc2, 0x5f, 0x87, 0xf9, 0x96, + 0xb8, 0x8b, 0x9, 0xd9, 0xfd, 0xcb, 0xfc, 0xcf, 0xb7, 0xa8, + 0xaf, 0x8a, 0x17, 0xf6, 0x9f, 0xf1, 0xe8, 0x1c, 0xea, 0x36, + 0xed, 0xf5, 0xb4, 0x4f, 0xf0, 0xa7, 0x8f, 0xda, 0x8b, 0xc7, + 0x7f, 0xf3, 0xfb, 0x69, 0xff, 00, 0x80, 0xab, 0x57, 0xfe, + 0xb0, 0x61, 0x7b, 0x4b, 0xee, 0x5f, 0xe6, 0x57, 0xfa, 0xc3, + 0x83, 0xf3, 0xfb, 0xbf, 0xe0, 0x9f, 0x6a, 0x51, 0x5f, 0x17, + 0xaf, 0xed, 0x4f, 0xe3, 0x90, 0x46, 0x6e, 0x2c, 0xdb, 0xd8, + 0xdb, 0xa, 0x9e, 0x2f, 0xda, 0xb7, 0xc6, 0xb1, 0xb1, 0x2c, + 0x74, 0xf9, 0x6, 0x3a, 0x35, 0xb9, 0xfe, 0x86, 0x9f, 0xfa, + 0xc1, 0x84, 0xed, 0x2f, 0xbb, 0xfe, 0x9, 0x4b, 0x88, 0x30, + 0x5d, 0xdf, 0xdc, 0x7d, 0x93, 0x45, 0x7c, 0x7e, 0xbf, 0xb5, + 0xbf, 0x8b, 0x82, 0x80, 0x6d, 0x34, 0xb6, 0x3e, 0xbe, 0x4b, + 0xff, 00, 0xf1, 0x55, 0x3a, 0x7e, 0xd7, 0x9e, 0x29, 0xc, + 0xb, 0x69, 0xba, 0x5b, 0xe, 0xe3, 0x63, 0x8f, 0xfd, 0x9a, + 0xad, 0x67, 0xd8, 0x3f, 0x3f, 0xb8, 0xb5, 0x9f, 0x60, 0x7f, + 0x99, 0xfd, 0xc7, 0xd7, 0x34, 0x57, 0xc9, 0xab, 0xfb, 0x60, + 0xf8, 0x88, 0x67, 0x76, 0x8d, 0xa6, 0x1f, 0xa1, 0x90, 0x7f, + 0xec, 0xd4, 0xf1, 0xfb, 0x61, 0xeb, 0xdd, 0xf4, 0x3d, 0x37, + 0xfe, 0xfa, 0x93, 0xfc, 0x6a, 0xbf, 0xb7, 0x70, 0x5f, 0xcc, + 0xfe, 0xe6, 0x57, 0xf6, 0xee, 0x7, 0xf9, 0x9f, 0xdc, 0xcf, + 0xab, 0xe8, 0xaf, 0x94, 0xd7, 0xf6, 0xc4, 0xd6, 0xf8, 0xce, + 0x85, 0xa7, 0x9f, 0xa4, 0x8f, 0xfe, 0x35, 0x22, 0xfe, 0xd8, + 0x9a, 0xb6, 0x79, 0xd0, 0x2c, 0x88, 0xf6, 0x99, 0xe9, 0xff, + 00, 0x6e, 0x60, 0xbf, 0x99, 0xfd, 0xcc, 0x7f, 0xdb, 0x98, + 0x1f, 0xe7, 0xfc, 0x19, 0xf5, 0x45, 0x15, 0xf2, 0xf4, 0x7f, + 0xb6, 0x35, 0xe8, 0x5f, 0x9f, 0xc3, 0x76, 0xe5, 0xbd, 0x56, + 0xe9, 0x80, 0xff, 00, 0xd0, 0x6a, 0x65, 0xfd, 0xb2, 0x26, + 0xe3, 0x3e, 0x18, 0x8f, 0xdf, 0x17, 0x87, 0xff, 00, 0x88, + 0xaa, 0x59, 0xde, 0x7, 0xf9, 0xff, 00, 0x7, 0xfe, 0x45, + 0x2c, 0xeb, 0x2, 0xff, 00, 0xe5, 0xe7, 0xe0, 0xff, 00, + 0xc8, 0xfa, 0x6e, 0x8a, 0xf9, 0xba, 0x3f, 0xdb, 0x22, 0xc, + 0xfc, 0xfe, 0x17, 0x90, 0xf, 0xf6, 0x6f, 0x47, 0xff, 00, + 0x11, 0x5b, 0xda, 0x47, 0xed, 0x6f, 0xe1, 0x6b, 0xb8, 0xd7, + 0xed, 0xf6, 0x37, 0xf6, 0x12, 0x13, 0x82, 0x15, 0x56, 0x55, + 0x3, 0xd7, 0x20, 0x83, 0xfa, 0x56, 0xb0, 0xcd, 0xf0, 0x33, + 0x76, 0x55, 0x3f, 0x35, 0xf9, 0xa3, 0x58, 0x66, 0xd8, 0x29, + 0xbb, 0x2a, 0x8b, 0xf1, 0x5f, 0x99, 0xee, 0x74, 0x57, 0x31, + 0xe1, 0xaf, 0x89, 0x9e, 0x17, 0xf1, 0x7b, 0x4, 0xd2, 0x75, + 0xbb, 0x4b, 0xb9, 0x8f, 0x3e, 0x4e, 0xfd, 0xb2, 0x7f, 0xdf, + 0x2d, 0x83, 0xfa, 0x57, 0x4f, 0x5e, 0xac, 0x2a, 0x42, 0xa2, + 0xe6, 0x83, 0xba, 0xf2, 0x3d, 0x48, 0x4e, 0x15, 0x17, 0x34, + 0x1d, 0xd7, 0x90, 0x51, 0x45, 0x15, 0x65, 0x85, 0x14, 0x51, + 0x40, 0x5, 0x14, 0x51, 0x40, 0x5, 0x14, 0x51, 0x40, 0x5, + 0x14, 0x51, 0x40, 0x5, 0x70, 0x7f, 0x18, 0x7e, 0x28, 0xdb, + 0x7c, 0x2f, 0xf0, 0xc3, 0xdd, 0xfe, 0xee, 0x7d, 0x4e, 0x73, + 0xe5, 0xda, 0x5a, 0xbb, 0x63, 0x7b, 0x77, 0x62, 0x3a, 0xed, + 0x1d, 0x4f, 0xe0, 0x3b, 0xd7, 0x75, 0x24, 0x8b, 0x12, 0x33, + 0xbb, 0x5, 0x45, 0x4, 0x96, 0x3d, 00, 0xaf, 0x82, 0x7e, + 0x32, 0x7c, 0x40, 0x7f, 0x88, 0xde, 0x3a, 0xbd, 0xbf, 0x57, + 0x26, 0xc2, 0x13, 0xf6, 0x7b, 0x34, 0xcf, 0x2, 0x35, 0x3d, + 0x7f, 0xe0, 0x47, 0x27, 0xf1, 0xaf, 0x17, 0x35, 0xc6, 0xbc, + 0x1d, 0xf, 0x73, 0xe2, 0x96, 0x8b, 0xfc, 0xcf, 0xf, 0x37, + 0xc7, 0xfd, 0x46, 0x87, 0xb9, 0xf1, 0xcb, 0x45, 0xfe, 0x7f, + 0x23, 0xa3, 0xf8, 0x39, 0xa7, 0xea, 0x1f, 0x13, 0x7e, 0x2a, + 0xc5, 0xa9, 0x6a, 0x92, 0xbd, 0xe3, 0xac, 0x86, 0xe2, 0x79, + 0x24, 0x39, 0xfa, 0xf, 0x61, 0xe8, 0x2b, 0xed, 0x40, 0x2, + 0x80, 0x7, 00, 0x57, 0x83, 0xfe, 0xca, 0x7e, 0x10, 0xfe, + 0xcc, 0xf0, 0xd5, 0xce, 0xb1, 0x34, 0x78, 0x9a, 0xe9, 0xf6, + 0xa1, 0x23, 0xf8, 0x45, 0x7b, 0xcd, 0x63, 0x92, 0x50, 0x74, + 0xb0, 0xbe, 0xd2, 0x5b, 0xcd, 0xdf, 0xfc, 0x83, 0x27, 0xa0, + 0xe9, 0x61, 0x54, 0xa7, 0xf1, 0x4b, 0x56, 0x14, 0x51, 0x45, + 0x7d, 0x1, 0xee, 0x5, 0x14, 0x51, 0x40, 0x5, 0x14, 0x84, + 0x64, 0x70, 0x71, 0xef, 0x40, 0x18, 0x1c, 0x92, 0x7e, 0xb4, + 00, 0xb4, 0x53, 0x2, 0xed, 0x39, 0xde, 0x48, 0xf4, 0x3d, + 0x29, 0xc0, 0x83, 0xd0, 0xe6, 0x80, 0x16, 0x8a, 0x28, 0xa0, + 0x2, 0x8a, 0x28, 0xa0, 0x2, 0x8a, 0x28, 0xa0, 0x2, 0x8a, + 0x28, 0xa0, 0x2, 0x8a, 0x28, 0xa0, 0x2, 0x8a, 0x28, 0xa0, + 0x2, 0x8a, 0x28, 0xa0, 0x2, 0x8a, 0x28, 0xa0, 0x2, 0x8a, + 0x28, 0xa0, 0x2, 0x8a, 0x28, 0xa0, 0x2, 0x93, 0x2, 0x96, + 0x8a, 00, 0x4c, 0xf, 0x4a, 0x4d, 0x8a, 0x7b, 0xf, 0xca, + 0x9d, 0x45, 00, 0x37, 0xca, 0x43, 0xfc, 0xb, 0xf9, 0x53, + 0x4c, 0x11, 0x1e, 0xb1, 0xa7, 0xfd, 0xf2, 0x2a, 0x4a, 0x29, + 0x58, 0x8, 0xbe, 0xcb, 0xf, 0xfc, 0xf1, 0x8f, 0xfe, 0xf9, + 0x14, 0xd3, 0x65, 0x6e, 0x7a, 0xc1, 0x17, 0xfd, 0xf0, 0x2a, + 0x7a, 0x28, 0xb2, 0x15, 0x91, 0x59, 0xb4, 0xeb, 0x46, 0xeb, + 0x6b, 0x9, 0xfa, 0xc6, 0x29, 0x87, 0x47, 0xb1, 0x6e, 0xb6, + 0x70, 0x1f, 0xac, 0x63, 0xfc, 0x2a, 0xe5, 0x14, 0xb9, 0x63, + 0xd8, 0x2c, 0xbb, 0x19, 0xe7, 0x40, 0xd3, 0x1b, 0xad, 0x85, + 0xb1, 0xff, 00, 0xb6, 0x4b, 0xfe, 0x14, 0xc6, 0xf0, 0xce, + 0x92, 0xdd, 0x74, 0xdb, 0x53, 0xff, 00, 0x6c, 0x85, 0x69, + 0xd1, 0x4b, 0xd9, 0xc3, 0xb2, 0x17, 0x2c, 0x7b, 0x19, 0x7, + 0xc2, 0x3a, 0x2b, 0x75, 0xd2, 0xed, 0x4f, 0xfd, 0xb2, 0x15, + 0x1b, 0x78, 0x2b, 0x41, 0x73, 0x93, 0xa4, 0x59, 0x93, 0xef, + 0xa, 0xd6, 0xdd, 0x15, 0x3e, 0xca, 0x9b, 0xfb, 0x2b, 0xee, + 0x17, 0x24, 0x3b, 0x1c, 0xf3, 0x7c, 0x3f, 0xf0, 0xe3, 0x75, + 0xd1, 0xed, 0x3f, 0xef, 0xd0, 0xa8, 0x9b, 0xe1, 0xaf, 0x86, + 0x1f, 0xae, 0x8b, 0x69, 0xff, 00, 0x7e, 0xc5, 0x74, 0xd4, + 0x54, 0xfd, 0x5e, 0x8b, 0xfb, 0xb, 0xee, 0x44, 0xfb, 0x2a, + 0x6f, 0xec, 0xaf, 0xb8, 0xe4, 0xdf, 0xe1, 0x5f, 0x85, 0x5f, + 0x39, 0xd1, 0x6d, 0xb9, 0xff, 00, 0x60, 0x54, 0x2d, 0xf0, + 0x87, 0xc2, 0x4f, 0xd7, 0x45, 0xb7, 0xff, 00, 0xbe, 0x6b, + 0xb2, 0xa2, 0xa3, 0xea, 0xb4, 0x1f, 0xd8, 0x5f, 0x72, 0x17, + 0xb0, 0xa5, 0xfc, 0xab, 0xee, 0x38, 0x76, 0xf8, 0x2f, 0xe0, + 0xf7, 0xeb, 0xa3, 0x41, 0xf9, 0x54, 0x2f, 0xf0, 0x2f, 0xc1, + 0x8f, 0xff, 00, 0x30, 0x78, 0xc7, 0xd2, 0xbb, 0xea, 0x2a, + 0x5e, 0xb, 0xc, 0xf7, 0xa6, 0xbe, 0xe4, 0x4f, 0xd5, 0xa8, + 0xbf, 0xb0, 0xbe, 0xe3, 0xce, 0x9f, 0xe0, 0x17, 0x83, 0x1f, + 0xfe, 0x61, 0x6a, 0x3e, 0x86, 0xa0, 0x7f, 0xd9, 0xe3, 0xc1, + 0x8f, 0xff, 00, 0x2e, 0x4, 0x7d, 0xd, 0x7a, 0x65, 0x15, + 0xf, 0x1, 0x84, 0x7f, 0xf2, 0xe9, 0x7d, 0xc8, 0x9f, 0xaa, + 0x50, 0x7f, 0x61, 0x7d, 0xc7, 0x96, 0xbf, 0xec, 0xe1, 0xe0, + 0xd7, 0xff, 00, 0x97, 0x37, 0x1f, 0xf0, 0x2a, 0x81, 0xff, + 00, 0x66, 0x7f, 0x7, 0x37, 0xfc, 0xb0, 0x94, 0x7d, 0x1a, + 0xbd, 0x66, 0x8a, 0x9f, 0xec, 0xdc, 0x1b, 0xff, 00, 0x97, + 0x4b, 0xee, 0x23, 0xea, 0x58, 0x67, 0xff, 00, 0x2e, 0xd7, + 0xdc, 0x79, 0x3, 0xfe, 0xcb, 0xfe, 0xf, 0x7f, 0xe0, 0xb8, + 0x5f, 0xa3, 0xd4, 0xd, 0xfb, 0x2c, 0x78, 0x4c, 0xf4, 0x7b, + 0x81, 0xf8, 0x8a, 0xf6, 0x6a, 0x2a, 0x1e, 0x57, 0x82, 0x7f, + 0xf2, 0xe9, 0x12, 0xf0, 0x18, 0x57, 0xff, 00, 0x2e, 0xd7, + 0xdc, 0x78, 0x9b, 0xfe, 0xca, 0x7e, 0x16, 0x6e, 0x97, 0x17, + 0x23, 0xf1, 0x15, 0xb, 0xfe, 0xc9, 0xbe, 0x1b, 0x6f, 0xbb, + 0x79, 0x72, 0x3f, 0x2a, 0xf7, 0x2a, 0x2a, 0x7f, 0xb2, 0x70, + 0x3f, 0xf3, 0xe9, 0x12, 0xf2, 0xec, 0x23, 0xff, 00, 0x97, + 0x68, 0xf0, 0x76, 0xfd, 0x92, 0x74, 0x3, 0xd3, 0x50, 0xb9, + 0x1f, 0x80, 0xa8, 0x5b, 0xf6, 0x45, 0xd1, 0xf, 0x4d, 0x52, + 0xe0, 0x7f, 0xc0, 0x45, 0x7b, 0xf5, 0x15, 0x3f, 0xd9, 0x18, + 0x1f, 0xf9, 0xf7, 0xf9, 0x90, 0xf2, 0xbc, 0x1b, 0xff, 00, + 0x97, 0x68, 0xf9, 0xe9, 0xff, 00, 0x64, 0x2d, 0x2c, 0xfd, + 0xdd, 0x62, 0x7f, 0xc5, 0x5, 0x40, 0xff, 00, 0xb2, 0x5, + 0x97, 0xf0, 0xeb, 0x12, 0x7e, 0x28, 0x2b, 0xe8, 0xca, 0x2a, + 0x3f, 0xb1, 0xb0, 0x3f, 0xf3, 0xef, 0xf1, 0x7f, 0xe6, 0x4b, + 0xca, 0x70, 0x4f, 0xfe, 0x5d, 0xa3, 0xe6, 0xd6, 0xfd, 0x90, + 0x21, 0xfe, 0x1d, 0x65, 0xbf, 0x14, 0xa8, 0x5f, 0xf6, 0x40, + 0x3f, 0xc3, 0xac, 0x7e, 0x69, 0x5f, 0x4c, 0x51, 0x53, 0xfd, + 0x89, 0x81, 0xfe, 0x4f, 0xc5, 0x91, 0xfd, 0x91, 0x82, 0xff, + 00, 0x9f, 0x67, 0xcc, 0xf, 0xfb, 0x20, 0x4f, 0xfc, 0x3a, + 0xba, 0xfe, 0x2b, 0x50, 0xbf, 0xec, 0x83, 0x7e, 0x3e, 0xee, + 0xaf, 0x11, 0xfa, 0xad, 0x7d, 0x4b, 0x45, 0x4f, 0xf6, 0x1e, + 0x7, 0xf9, 0x5f, 0xde, 0xc9, 0x79, 0x36, 0x5, 0xfd, 0x83, + 0xe5, 0x37, 0xfd, 0x91, 0x35, 0x51, 0xd3, 0x53, 0x84, 0xfe, + 0x15, 0x3, 0xfe, 0xc9, 0x1a, 0xd8, 0xe9, 0x7d, 0xb, 0x57, + 0xd6, 0x74, 0x54, 0xbc, 0x87, 0x5, 0xd9, 0xfd, 0xec, 0x87, + 0x92, 0x60, 0x7f, 0x93, 0xf1, 0x3e, 0x46, 0x7f, 0xd9, 0x33, + 0xc4, 0x23, 0xa5, 0xd4, 0x7, 0xf1, 0xa8, 0x1f, 0xf6, 0x51, + 0xf1, 0x28, 0xfb, 0xb2, 0xc2, 0x7f, 0x1a, 0xfb, 0x2, 0x8a, + 0x8f, 0xec, 0xc, 0x1f, 0x9f, 0xde, 0x4f, 0xf6, 0x16, 0xb, + 0xf9, 0x7f, 0x13, 0xe3, 0x87, 0xfd, 0x95, 0x7c, 0x54, 0x3e, + 0xe9, 0x85, 0xbf, 0xe0, 0x42, 0xa1, 0x7f, 0xd9, 0x6f, 0xc5, + 0xeb, 0xd2, 0x38, 0x8f, 0xd1, 0xc5, 0x7d, 0x9b, 0x45, 0x4f, + 0xfa, 0xbf, 0x84, 0xee, 0xfe, 0xff, 00, 0xf8, 0x4, 0xff, + 00, 0x60, 0xe0, 0xbb, 0x3f, 0xbc, 0xf8, 0xad, 0xff, 00, + 0x66, 0x3f, 0x18, 0xaf, 0x4b, 0x64, 0x3f, 0xf0, 0x31, 0x50, + 0xbf, 0xec, 0xd7, 0xe3, 0x35, 0xff, 00, 0x97, 0x20, 0x7f, + 0xe0, 0x42, 0xbe, 0xda, 0xa2, 0xa7, 0xfd, 0x5e, 0xc3, 0x7f, + 0x34, 0xbf, 0xf, 0xf2, 0x23, 0xfd, 0x5f, 0xc1, 0xf9, 0xfd, + 0xe7, 0xc3, 0xcd, 0xfb, 0x39, 0xf8, 0xd1, 0x7f, 0xe6, 0x1a, + 0x4f, 0xfc, 0x8, 0x54, 0x2f, 0xfb, 0x3d, 0xf8, 0xd1, 0x7f, + 0xe6, 0x14, 0xe7, 0xf1, 0x15, 0xf7, 0x3d, 0x15, 0x3f, 0xea, + 0xee, 0x1f, 0xf9, 0xe5, 0xf8, 0x7f, 0x91, 0x3f, 0xea, 0xf6, + 0x13, 0xcf, 0xef, 0x3e, 0x12, 0x3f, 0x1, 0xbc, 0x6d, 0xb, + 0x6, 0x5d, 0x22, 0x60, 0xc3, 0xa3, 0x29, 0xc1, 0x15, 0xde, + 0x78, 0x43, 0xc6, 0xbf, 0x14, 0xfe, 0x15, 0x6c, 0x5d, 0x57, + 0x4c, 0xbc, 0xd7, 0x34, 0x55, 0xfb, 0xf0, 0x5d, 0x12, 0xd2, + 0xa2, 0xff, 00, 0xb1, 0x27, 0x5f, 0xc0, 0xe4, 0x7d, 0x2b, + 0xeb, 0x1a, 0x82, 0xf2, 0xde, 0x2b, 0x9b, 0x69, 0x12, 0x64, + 0x59, 0x10, 0xa9, 0xc8, 0x61, 0x5a, 0xd2, 0xc9, 0x56, 0x19, + 0xf3, 0xd0, 0xab, 0x24, 0xfe, 0x45, 0x53, 0xc8, 0xe9, 0xd0, + 0x7c, 0xf8, 0x7a, 0x92, 0x8b, 0xfe, 0xb7, 0xee, 0x73, 0xbe, + 00, 0xf8, 0x91, 0xa2, 0x7c, 0x48, 0xd2, 0x8d, 0xe6, 0x91, + 0x73, 0xba, 0x58, 0xf0, 0x2e, 0x2d, 0x24, 0xf9, 0x66, 0xb7, + 0x63, 0xfc, 0x2e, 0xbd, 0xbe, 0xbd, 0xd, 0x75, 0x35, 0xf1, + 0x7, 0xc4, 0x6d, 0x72, 0xff, 00, 0xe1, 0x4f, 0xc4, 0x43, + 0xae, 0x78, 0x66, 0x63, 0x69, 0x74, 0x24, 0xfd, 0xfc, 0x20, + 0xfe, 0xee, 0xe1, 0x1, 0xc9, 0x8d, 0xc7, 0x70, 0x7f, 0x31, + 0xda, 0xbe, 0xae, 0xf8, 0x4f, 0xf1, 0x3b, 0x4d, 0xf8, 0xb7, + 0xe0, 0xcb, 0x5d, 0x7f, 0x4d, 0x47, 0x80, 0x3b, 0x34, 0x53, + 0xda, 0xca, 0x46, 0xf8, 0x25, 0x5e, 0x19, 0xf, 0xaf, 0xa8, + 0x3d, 0xc1, 0x6, 0xbd, 0xc, 0xe, 0x35, 0x62, 0x79, 0xa9, + 0xcb, 0xe2, 0x8e, 0x8c, 0xe8, 0xc0, 0x66, 0x4a, 0xbd, 0x59, + 0x61, 0x6a, 0xe9, 0x52, 0x3f, 0x73, 0x5d, 0xd7, 0xea, 0x8e, + 0xc6, 0x8a, 0x28, 0xaf, 0x54, 0xf7, 0x42, 0x8a, 0x28, 0xa0, + 0x2, 0x8a, 0x28, 0xa0, 0x2, 0x8a, 0x28, 0xa0, 0xf, 0x37, + 0xfd, 0xa0, 0x7c, 0x6a, 0x3c, 0x17, 0xf0, 0xd7, 0x51, 0x74, + 0x72, 0x97, 0x97, 0xe3, 0xec, 0x56, 0xfb, 0x4e, 0x8, 0x67, + 0x7, 0x24, 0x7d, 0x17, 0x26, 0xbe, 0x25, 0xd0, 0xb4, 0xb9, + 0x35, 0x8d, 0x56, 0xd2, 0xca, 0x15, 0xdc, 0xf3, 0x48, 0x10, + 0x1, 0x5e, 0xd3, 0xfb, 0x5a, 0xf8, 0xcb, 0xfb, 0x5b, 0xc6, + 0x16, 0x7e, 0x1f, 0x85, 0xf3, 0x6, 0x97, 0x1f, 0x99, 0x28, + 0x7, 0x83, 0x33, 0x8c, 0xfe, 0x8b, 0x8f, 0xfb, 0xe8, 0xd6, + 0x77, 0xec, 0xc3, 0xe1, 0x1, 0xaf, 0x78, 0xd8, 0x5f, 0x4d, + 0x1e, 0xeb, 0x7b, 0x25, 0x2f, 0x93, 0xd3, 0x77, 0x6a, 0xfc, + 0xf7, 0x33, 0x93, 0xc7, 0x63, 0xd6, 0x1e, 0x3b, 0x2d, 0x3f, + 0xcc, 0xfc, 0xef, 0x1e, 0xde, 0x63, 0x9a, 0x2a, 0x11, 0xda, + 0x3a, 0x7f, 0x9f, 0xf5, 0xe4, 0x7d, 0x67, 0xe1, 0x3d, 0x12, + 0x3f, 0xe, 0xf8, 0x72, 0xc3, 0x4f, 0x8d, 0x42, 0x88, 0x22, + 0x55, 0x38, 0xf5, 0xc7, 0x35, 0xaf, 0x45, 0x15, 0xfa, 0x4, + 0x62, 0xa1, 0x15, 0x18, 0xec, 0x8f, 0xd0, 0xa2, 0x94, 0x52, + 0x48, 0x28, 0xa2, 0x8a, 0xa2, 0x82, 0x8a, 0x2b, 0xcd, 0xbf, + 0x68, 0xaf, 0x8d, 0xda, 0x47, 0xec, 0xf1, 0xf0, 0x83, 0xc4, + 0x1e, 0x39, 0xd6, 0xe, 0xe8, 0xf4, 0xf8, 0x71, 0x6d, 0x6e, + 0x3e, 0xf5, 0xc5, 0xc3, 0x7c, 0xb1, 0x44, 0x3e, 0xac, 0x46, + 0x7d, 0x6, 0x4f, 0x6a, 00, 0xe7, 0x3f, 0x69, 0x9f, 0xda, + 0xf3, 0xe1, 0xf7, 0xec, 0xaf, 0xa0, 0x47, 0x79, 0xe2, 0xcb, + 0xe7, 0x9f, 0x55, 0xba, 0x52, 0xd6, 0x3a, 0x25, 0x88, 0xf, + 0x77, 0x73, 0x8e, 0xe0, 0x67, 0xa, 0x99, 0xfe, 0x36, 0x20, + 0x7d, 0x4f, 0x15, 0xf9, 0x5d, 0xf1, 0x87, 0xfe, 0xa, 0xd5, + 0xf1, 0x9b, 0xe2, 0x5, 0xc5, 0xdd, 0xbf, 0x85, 0xe5, 0xb1, + 0xf0, 0x1e, 0x90, 0xec, 0x44, 0x4b, 0xa7, 0xc2, 0x26, 0xbb, + 0x9, 0x9e, 0x37, 0x4d, 0x26, 0x46, 0x71, 0xfd, 0xd5, 0x5a, + 0xf9, 0xb3, 0x5d, 0xd7, 0xfc, 0x7d, 0xfb, 0x57, 0x7c, 0x67, + 0x4b, 0x8b, 0xc9, 0x2e, 0x3c, 0x4b, 0xe3, 0x3f, 0x11, 0xdd, + 0xac, 0x10, 0x44, 0xf, 00, 0x93, 0xf2, 0xc6, 0x83, 0xa2, + 0x46, 0xa3, 0x3c, 0x74, 00, 0x13, 0xea, 0x6b, 0xf4, 0x67, + 0xc1, 0x1f, 0xf0, 0x48, 0xaf, 0x87, 0xff, 00, 0xf, 0x7e, + 0x1c, 0xdf, 0x78, 0x9b, 0xe2, 0xf7, 0x8b, 0x75, 0x1b, 0xeb, + 0x9d, 0x3e, 0xca, 0x4b, 0xeb, 0xe8, 0x74, 0x69, 0x56, 0xda, + 0xd6, 0xd9, 0x11, 0xb, 0xb0, 0xe, 0xca, 0x59, 0xf0, 0x1, + 0xe7, 0xe5, 0xcf, 0xa5, 0x32, 0x6e, 0xde, 0xc7, 0xe7, 0x17, + 0x88, 0x7f, 0x68, 0xbf, 0x8a, 0x7e, 0x2b, 0xb9, 0x92, 0x7d, + 0x5b, 0xe2, 0x37, 0x8a, 0x2f, 0x64, 0x90, 0xe5, 0x83, 0xea, + 0xf3, 0x85, 0x27, 0xfd, 0xd0, 0xc0, 0xf, 0xca, 0xbf, 0x5a, + 0xbf, 0xe0, 0x92, 0x3e, 0xb, 0xd6, 0xed, 0xfe, 0x3, 0xea, + 0x3e, 0x39, 0xf1, 0x6, 0xad, 0xa9, 0x6a, 0xb7, 0x9e, 0x23, + 0xbe, 0x74, 0xb3, 0x17, 0xf7, 0x52, 0x4c, 0x22, 0xb6, 0x80, + 0x94, 0x1b, 0x43, 0x13, 0x8d, 0xd2, 0x79, 0x84, 0x91, 0xd4, + 0x5, 0xaf, 0xc7, 0x4d, 0x1b, 0xc3, 0x7f, 0xf0, 0x9e, 0xfc, + 0x44, 0xb2, 0xd0, 0x7c, 0x39, 0x6f, 0x24, 0x4b, 0xac, 0x6a, + 0x89, 0x67, 0xa7, 0xc1, 0x2b, 0x6f, 0x64, 0x12, 0xca, 0x16, + 0x30, 0xcd, 0x8e, 0x70, 0x18, 0x64, 0xfb, 0x13, 0x5f, 0xd1, + 0xcf, 0x86, 0xb4, 0x4d, 0x3, 0xf6, 0x7b, 0xf8, 0x2d, 0x65, + 0xa6, 0xc6, 0x52, 0xcf, 0xc3, 0xfe, 0x13, 0xd1, 0xc0, 0x67, + 0x3c, 0x1, 0x1c, 0x31, 0xe5, 0xdc, 0xfb, 0x9c, 0x12, 0x7d, + 0xcd, 0xc, 0x48, 0xf8, 0xf, 0xc4, 0x7f, 0xf0, 0x59, 0xa9, + 0xfc, 0x25, 0xe2, 0xcd, 0x6b, 0x42, 0xd4, 0x3e, 0x14, 0xab, + 0xcd, 0xa6, 0x5e, 0xcf, 0x65, 0x24, 0x90, 0x6b, 0x7c, 0x33, + 0x47, 0x23, 0x21, 0x20, 0x18, 0x7d, 0x56, 0xbe, 0xec, 0xfd, + 0x9c, 0x3e, 0x34, 0x47, 0xfb, 0x42, 0x7c, 0x1b, 0xf0, 0xff, + 00, 0x8f, 0x62, 0xd2, 0xdf, 0x46, 0x4d, 0x59, 0x24, 0x61, + 0x64, 0xf2, 0xf9, 0xa6, 0x3d, 0xb2, 0x32, 0x7d, 0xec, 0xc, + 0xe7, 0x6e, 0x7a, 0x77, 0xaf, 0xe7, 0x2f, 0xc6, 0x7a, 0xf9, + 0xf1, 0x5f, 0x8b, 0xf5, 0xdd, 0x6d, 0x86, 0xd6, 0xd4, 0xaf, + 0xe7, 0xbd, 0x23, 0xd0, 0xc9, 0x23, 0x3f, 0xfe, 0xcd, 0x5f, + 0xd1, 0x27, 0xec, 0x91, 0xf0, 0xfe, 0x4f, 0x85, 0xff, 00, + 0xb3, 0x57, 0xc3, 0x9f, 0xd, 0xce, 0x9e, 0x5d, 0xdd, 0xae, + 0x8d, 0x3, 0xdc, 0xaf, 0xa4, 0xd2, 0x2f, 0x99, 0x27, 0xfe, + 0x3c, 0xe6, 0x81, 0xa7, 0x73, 0xd6, 0xc9, 0xc0, 0xc9, 0xe0, + 0x57, 0xce, 0xda, 0xff, 00, 0xed, 0xf, 0xae, 0x43, 0xae, + 0x5f, 0x47, 0xa6, 0xc7, 0x64, 0xda, 0x7a, 0x4a, 0xcb, 0x9, + 0x96, 0x26, 0x2c, 0x54, 0x1c, 0x64, 0x9d, 0xc3, 0xaf, 0x5f, + 0xc6, 0xbd, 0x7b, 0xe2, 0x97, 0x89, 0x47, 0x85, 0xbc, 0x11, + 0xa9, 0x5d, 0xab, 0x6d, 0x9d, 0xd3, 0xc8, 0x87, 0xfd, 0xf7, + 0xe0, 0x7e, 0x5c, 0x9f, 0xc2, 0xbe, 0x40, 0xaf, 0x86, 0xe2, + 0x2c, 0xca, 0xae, 0x1a, 0x70, 0xa3, 0x42, 0x5c, 0xaf, 0x77, + 0x6f, 0xc3, 0xf5, 0x3c, 0x9c, 0x75, 0x79, 0x53, 0x6a, 0x10, + 0x76, 0x3d, 0x5d, 0x3f, 0x69, 0xf, 0x12, 0xaf, 0xde, 0xb3, + 0xd3, 0x9b, 0xfe, 0xd9, 0xb8, 0xff, 00, 0xd9, 0xaa, 0x74, + 0xfd, 0xa5, 0x75, 0xe1, 0xf7, 0xb4, 0xdd, 0x3d, 0xbe, 0x81, + 0xc7, 0xfe, 0xcd, 0x5e, 0x43, 0x45, 0x7c, 0x82, 0xce, 0x73, + 0x5, 0xff, 00, 0x2f, 0x5f, 0xe0, 0x79, 0x9f, 0x5a, 0xad, + 0xfc, 0xc7, 0xb3, 0x47, 0xfb, 0x4c, 0xea, 0x83, 0xef, 0xe8, + 0xb6, 0x8d, 0xfe, 0xec, 0xac, 0x3f, 0xc6, 0xa7, 0x4f, 0xda, + 0x72, 0xef, 0xf8, 0xbc, 0x3f, 0x9, 0xfa, 0x5d, 0x11, 0xff, + 00, 0xb2, 0xd7, 0x89, 0x51, 0x5a, 0x2c, 0xf3, 0x31, 0x5f, + 0xf2, 0xf7, 0xf0, 0x5f, 0xe4, 0x57, 0xd7, 0x2b, 0xff, 00, + 0x31, 0xee, 0xd1, 0x7e, 0xd3, 0x83, 0xfe, 0x5a, 0x78, 0x7f, + 0x1f, 0xee, 0xdd, 0x7f, 0xf6, 0x35, 0x66, 0x3f, 0xda, 0x6e, + 0xc8, 0xfd, 0xfd, 0xa, 0x71, 0xfe, 0xec, 0xea, 0x7f, 0xa5, + 0x78, 0x5, 0x15, 0xaa, 0xe2, 0xc, 0xc5, 0x7f, 0xcb, 0xcf, + 0xc1, 0x7f, 0x91, 0x5f, 0x5d, 0xaf, 0xfc, 0xdf, 0x91, 0xf4, + 0x3c, 0x7f, 0xb4, 0xc6, 0x90, 0x7e, 0xfe, 0x91, 0x7a, 0xbf, + 0xee, 0xb2, 0x1f, 0xeb, 0x5a, 0x56, 0x7f, 0xb4, 0x5f, 0x85, + 0xee, 0x8, 0x13, 0x45, 0x7f, 0x6b, 0xee, 0xf0, 0x86, 0x1f, + 0xf8, 0xeb, 0x1a, 0xf9, 0x9a, 0x8a, 0xd6, 0x3c, 0x47, 0x8f, + 0x8e, 0xed, 0x3f, 0x97, 0xf9, 0x14, 0xb1, 0xf5, 0x97, 0x53, + 0xec, 0x4d, 0x7, 0xe2, 0x67, 0x86, 0x7c, 0x48, 0xeb, 0x1d, + 0x8e, 0xaf, 0x3, 0x4c, 0xdd, 0x22, 0x97, 0x31, 0xb9, 0xfa, + 0x6, 0xc6, 0x7f, 0xa, 0xe9, 0xeb, 0xe1, 0x4a, 0xed, 0x7c, + 0x17, 0xf1, 0x6b, 0x5f, 0xf0, 0x6c, 0xa8, 0x89, 0x72, 0xd7, + 0xd6, 00, 0xfc, 0xd6, 0x97, 0x2c, 0x59, 0x71, 0xfe, 0xc9, + 0xea, 0xbf, 0x87, 0x1e, 0xd5, 0xed, 0xe1, 0x38, 0xa1, 0x36, + 0xa3, 0x8a, 0x85, 0xbc, 0xd7, 0xf9, 0x7f, 0xc1, 0x3a, 0xe9, + 0x66, 0x37, 0x76, 0xa8, 0xbe, 0xe3, 0xeb, 0x6a, 0x2b, 0x13, + 0xc2, 0x1e, 0x2f, 0xd3, 0xfc, 0x6b, 0xa3, 0xa6, 0xa1, 0xa7, + 0xc8, 0x4a, 0x13, 0xb6, 0x48, 0xdb, 0x86, 0x8d, 0xfb, 0xa9, + 0x15, 0xb7, 0x5f, 0x75, 0x4e, 0xa4, 0x6a, 0xc5, 0x4e, 0xe, + 0xe9, 0x9e, 0xc4, 0x64, 0xa4, 0xae, 0xb6, 0xa, 0xc0, 0xf1, + 0x17, 0x8e, 0xb4, 0x2f, 0x9, 0xdc, 0x43, 0x6, 0xab, 0xa8, + 0x25, 0xa4, 0xb3, 0x29, 0x74, 0x56, 0x56, 0x39, 00, 0xe3, + 0x3c, 0x3, 0x5b, 0xf5, 0xf2, 0x87, 0xc6, 0xed, 0x74, 0x6b, + 0x9f, 0x10, 0xaf, 0xc2, 0x36, 0xe8, 0xac, 0xc2, 0xda, 0xa7, + 0xfc, 0x7, 0xef, 0x7f, 0xe3, 0xc5, 0xab, 0xc8, 0xcd, 0xf3, + 0x7, 0x97, 0x61, 0xd5, 0x48, 0x24, 0xe4, 0xdd, 0x95, 0xce, + 0x5c, 0x55, 0x77, 0x42, 0x1c, 0xcb, 0x73, 0xe8, 0x4, 0xf8, + 0xb9, 0xe0, 0xf7, 0xe9, 0xaf, 0x5b, 0xf, 0xf7, 0xb7, 0xf, + 0xe6, 0x2a, 0x74, 0xf8, 0xa1, 0xe1, 0x37, 0xe9, 0xe2, 0xb, + 0x1f, 0xc6, 0x50, 0x2b, 0xe3, 0xca, 0x2b, 0xe3, 0x97, 0x14, + 0xe2, 0x7a, 0xd3, 0x8f, 0xe3, 0xfe, 0x67, 0x97, 0xfd, 0xa3, + 0x53, 0xb2, 0x3e, 0xca, 0x8f, 0xe2, 0x17, 0x86, 0x25, 0xfb, + 0xba, 0xfe, 0x9c, 0x7f, 0xed, 0xe5, 0x3f, 0xc6, 0xad, 0x47, + 0xe3, 0xd, 0xa, 0x6f, 0xb9, 0xac, 0xd8, 0x37, 0xd2, 0xe5, + 0x3f, 0xc6, 0xbe, 0x2b, 0xa2, 0xb5, 0x5c, 0x55, 0x5b, 0xad, + 0x25, 0xf7, 0xb2, 0xbf, 0xb4, 0x67, 0xd6, 0x27, 0xdb, 0x89, + 0xaf, 0x69, 0x92, 0x7d, 0xdd, 0x46, 0xd1, 0xbe, 0x93, 0xaf, + 0xf8, 0xd4, 0xc9, 0xa9, 0x5a, 0x49, 0xf7, 0x2e, 0xa0, 0x6f, + 0xa4, 0x80, 0xff, 00, 0x5a, 0xf8, 0x76, 0x8c, 0x91, 0x5a, + 0x2e, 0x2b, 0x97, 0x5a, 0x3f, 0x8f, 0xfc, 0x2, 0xbf, 0xb4, + 0x9f, 0xf2, 0xfe, 0x27, 0xdd, 0xb, 0x2a, 0x37, 0xdd, 0x75, + 0x3f, 0x43, 0x4e, 0xdc, 0x3d, 0x45, 0x7c, 0x30, 0x25, 0x75, + 0xe8, 0xec, 0x3e, 0x86, 0xa4, 0x4b, 0xeb, 0x98, 0xfe, 0xed, + 0xc4, 0xab, 0xf4, 0x72, 0x2b, 0x45, 0xc5, 0x6b, 0xad, 0x1f, + 0xfc, 0x9b, 0xfe, 0x1, 0x5f, 0xda, 0x5f, 0xdc, 0xfc, 0x7f, + 0xe0, 0x1f, 0x72, 0x51, 0x5f, 0x10, 0xa6, 0xb9, 0xa9, 0x47, + 0xf7, 0x75, 0xb, 0xa5, 0xfa, 0x4c, 0xdf, 0xe3, 0x52, 0xaf, + 0x89, 0xb5, 0x84, 0xfb, 0xba, 0xad, 0xf2, 0xfd, 0x2e, 0x5c, + 0x7f, 0x5a, 0xd1, 0x71, 0x5d, 0x3e, 0xb4, 0x5f, 0xdf, 0xff, + 00, 00, 0x7f, 0xda, 0x4b, 0xf9, 0x7f, 0x13, 0xed, 0x9a, + 0x2b, 0xe2, 0xc4, 0xf1, 0x96, 0xbf, 0x1f, 0xdd, 0xd7, 0x35, + 0x25, 0xfa, 0x5d, 0xc9, 0xfe, 0x35, 0xda, 0x7c, 0x25, 0xf1, + 0x7, 0x88, 0x75, 0xff, 00, 0x1e, 0xe9, 0x76, 0x93, 0x6b, + 0x3a, 0x84, 0xf6, 0xc1, 0xda, 0x59, 0x52, 0x4b, 0x97, 0x65, + 0x2a, 0xaa, 0x4e, 0x8, 0x27, 0xa6, 0x70, 0x3f, 0x1a, 0xe9, + 0xa1, 0xc4, 0xb4, 0xab, 0xd5, 0x8d, 0x25, 0x49, 0xde, 0x4d, + 0x2d, 0xd7, 0x53, 0x48, 0x63, 0xe3, 0x39, 0x28, 0xa8, 0xee, + 0x7d, 0x3f, 0x45, 0x14, 0x57, 0xd9, 0x1e, 0xa8, 0x51, 0x45, + 0x14, 00, 0x51, 0x5c, 0xf7, 0x88, 0xfc, 0x7f, 0xa0, 0x78, + 0x4f, 0x8d, 0x4f, 0x52, 0x86, 0x9, 0x7f, 0xe7, 0x8a, 0xe5, + 0xe4, 0xff, 00, 0xbe, 0x57, 0x26, 0xbc, 0xef, 0x5b, 0xfd, + 0xa5, 0x74, 0xcb, 0x70, 0xcb, 0xa5, 0xe9, 0x97, 0x17, 0x6f, + 0xd9, 0xee, 0x18, 0x44, 0xbf, 0x90, 0xc9, 0xfe, 0x55, 0xe6, + 0xe2, 0x33, 0x2c, 0x26, 0x17, 0x4a, 0xb5, 0x12, 0x7d, 0xb7, + 0x7f, 0x72, 0x39, 0xe7, 0x5e, 0x95, 0x3f, 0x8a, 0x47, 0xb2, + 0xd1, 0x5f, 0x34, 0x5f, 0x7e, 0xd1, 0x9e, 0x26, 0xb8, 0x63, + 0xf6, 0x78, 0x2c, 0x2d, 0x13, 0xb6, 0x22, 0x67, 0x23, 0xf1, + 0x2d, 0x8f, 0xd2, 0xb1, 0xae, 0x3e, 0x37, 0xf8, 0xce, 0x72, + 0x7f, 0xe2, 0x6d, 0xe5, 0x3, 0xda, 0x38, 0x23, 0x18, 0xff, + 00, 0xc7, 0x6b, 0xc5, 0x9f, 0x13, 0x60, 0x63, 0xf0, 0xa9, + 0x3f, 0x97, 0xf9, 0xb4, 0x72, 0x3c, 0xc2, 0x8a, 0xda, 0xec, + 0xfa, 0xbc, 0x8c, 0xd2, 0x79, 0x63, 0xdf, 0xf3, 0x35, 0xf2, + 0x2b, 0x7c, 0x5d, 0xf1, 0x83, 0x1c, 0x9d, 0x76, 0xe4, 0x7d, + 0x2, 0x8f, 0xe9, 0x52, 0x45, 0xf1, 0x8b, 0xc6, 0x31, 0x1c, + 0x8d, 0x72, 0x63, 0xfe, 0xf4, 0x68, 0xdf, 0xcd, 0x6b, 0xf, + 0xf5, 0xa3, 0x9, 0xfc, 0x92, 0xfc, 0x3f, 0xcc, 0x9f, 0xed, + 0x1a, 0x7d, 0x99, 0xf5, 0xc5, 0x15, 0xf2, 0xb5, 0xb7, 0xc7, + 0x9f, 0x18, 0xdb, 0xfd, 0xeb, 0xf8, 0x6e, 0x3f, 0xeb, 0xad, + 0xba, 0x7f, 0x40, 0x2b, 0x7f, 0x4d, 0xfd, 0xa5, 0x75, 0xa8, + 0x58, 0xb, 0xed, 0x32, 0xce, 0xe9, 0x7b, 0xf9, 0x25, 0xa2, + 0x3f, 0xa9, 0x61, 0x5d, 0x54, 0xf8, 0x93, 0x1, 0x3f, 0x8a, + 0xeb, 0xd5, 0x7f, 0x95, 0xcd, 0x16, 0x3e, 0x8b, 0xde, 0xe8, + 0xfa, 0x2a, 0x8a, 0xf2, 0xdd, 0x17, 0xf6, 0x87, 0xf0, 0xd6, + 0xa3, 0xb5, 0x6f, 0x52, 0xeb, 0x4c, 0x90, 0xf5, 0x32, 0x26, + 0xf4, 0xfc, 0xd7, 0x27, 0xf4, 0xaf, 0x45, 0xd2, 0xb5, 0x9b, + 0x1d, 0x72, 0xd5, 0x6e, 0x74, 0xfb, 0xb8, 0x6f, 0x20, 0x6e, + 0x8f, 0xb, 0x86, 0x1f, 0x8f, 0xa5, 0x7b, 0x98, 0x7c, 0x6e, + 0x1f, 0x15, 0xfc, 0x19, 0xa9, 0x7e, 0x7f, 0x76, 0xe7, 0x64, + 0x2a, 0xd3, 0xa9, 0xf0, 0x3b, 0x97, 0x68, 0xa2, 0x8a, 0xed, + 0x35, 0xa, 0x28, 0xa2, 0x80, 0xa, 0x28, 0xa2, 0x80, 0xa, + 0x28, 0xa2, 0x80, 0xa, 0x28, 0xa6, 0xbc, 0x8b, 0x12, 0x96, + 0x76, 0x8, 0xa3, 0xa9, 0x63, 0x81, 0x40, 0xe, 0xa2, 0xb0, + 0xb5, 0xf, 0x1d, 0xf8, 0x77, 0x4b, 0x24, 0x5d, 0x6b, 0x56, + 0x30, 0xb0, 0xea, 0xa6, 0x75, 0x27, 0xf2, 0x7, 0x35, 0x8b, + 0x71, 0xf1, 0xa7, 0xc1, 0xb6, 0xe7, 0x7, 0x5a, 0x47, 0xff, + 00, 0xae, 0x70, 0xc8, 0xff, 00, 0xc9, 0x6b, 0x92, 0x78, + 0xbc, 0x35, 0x3d, 0x27, 0x52, 0x2b, 0xd5, 0xa3, 0x27, 0x56, + 0x9c, 0x77, 0x92, 0xfb, 0xce, 0xde, 0x98, 0x5d, 0xb3, 0xf7, + 0xf, 0xe6, 0x2b, 0x82, 0x3f, 0x1d, 0xfc, 0x18, 0xf, 0xfc, + 0x84, 0xe4, 0x3f, 0xf6, 0xed, 0x2f, 0xff, 00, 0x13, 0x4a, + 0xbf, 0x1d, 0x7c, 0x18, 0xc7, 0xfe, 0x42, 0x8e, 0x3e, 0xb6, + 0xb2, 0xff, 00, 0xf1, 0x35, 0x8f, 0xf6, 0x8e, 0xb, 0xfe, + 0x7f, 0x47, 0xff, 00, 0x2, 0x44, 0xfb, 0x7a, 0x5f, 0xce, + 0xbe, 0xf3, 0xbe, 0xc9, 0xc7, 0x4a, 0x4d, 0xc7, 0xfb, 0xa7, + 0xf4, 0xae, 0x3e, 0xdf, 0xe3, 0xf, 0x83, 0xae, 0x7e, 0xee, + 0xb9, 0x2, 0x7f, 0xd7, 0x45, 0x74, 0xfe, 0x60, 0x56, 0xcd, + 0x8f, 0x8c, 0xb4, 0x1d, 0x4f, 0x1f, 0x65, 0xd6, 0x2c, 0x67, + 0x27, 0xa0, 0x59, 0xd7, 0x3f, 0x96, 0x6b, 0x78, 0x62, 0xb0, + 0xf5, 0x3e, 0xa, 0x89, 0xfa, 0x34, 0x5a, 0xa9, 0x9, 0x6d, + 0x24, 0x6c, 0xd1, 0x4d, 0x47, 0x59, 0x17, 0x2a, 0xc1, 0x87, + 0xa8, 0x39, 0xa7, 0x57, 0x51, 0xa0, 0x51, 0x45, 0x30, 0x31, + 0xf3, 0x4a, 0x9e, 0x98, 0xc8, 0x34, 00, 0xfa, 0x28, 0xa2, + 0x80, 0xa, 0x82, 0xf5, 0xfc, 0xbb, 0x39, 0xdb, 0xd1, 0x9, + 0xfd, 0x2a, 0x7a, 0xa3, 0xad, 0xbf, 0x97, 0xa4, 0x5d, 0xb1, + 0x38, 0xc4, 0x66, 0xa6, 0x4e, 0xc9, 0xb1, 0x3d, 0x13, 0x3e, + 0x1c, 0xf8, 0xdf, 0x37, 0xda, 0x3c, 0x49, 0x28, 0xeb, 0x82, + 0x6b, 0x2f, 0xf6, 0x63, 0xf8, 0x99, 0x27, 0xc3, 0x6f, 0x8d, + 0x16, 0xba, 0x44, 0xf2, 0x95, 0xd1, 0x3c, 0x4a, 0x45, 0xa4, + 0x88, 0x71, 0x84, 0xb8, 0x19, 0xf2, 0x9f, 0xdb, 0xba, 0x9f, + 0xf7, 0x85, 0x49, 0xf1, 0x56, 0x7f, 0x3f, 0xc4, 0xd7, 0x3d, + 0xf0, 0x4d, 0x78, 0x7, 0xc5, 0x7b, 0x89, 0x2c, 0xb4, 0xe1, + 0x75, 0x6e, 0xed, 0x15, 0xcd, 0xbb, 0x9, 0xa2, 0x91, 0x4e, + 0xa, 0xba, 0x9c, 0xa9, 0x1f, 0x88, 0xaf, 0xce, 0x32, 0xfa, + 0xce, 0x38, 0xc9, 0x49, 0x77, 0x67, 0xe3, 0x98, 0xbc, 0x4c, + 0xb0, 0xd9, 0xac, 0x31, 0x11, 0xe9, 0x24, 0xbe, 0x4f, 0x46, + 0x7e, 0xc0, 0x51, 0x5c, 0x1f, 0x80, 0xfe, 0x28, 0xe9, 0x5e, + 0x21, 0xf0, 0x37, 0x87, 0x75, 0x59, 0x2e, 0xcb, 0x49, 0x7d, + 0xa7, 0x5b, 0x5c, 0xb1, 0x2a, 0x72, 0x4b, 0xc4, 0xac, 0x7f, + 0x9d, 0x15, 0xfa, 0x45, 0xcf, 0xd8, 0xee, 0x99, 0xde, 0x51, + 0x45, 0x14, 0xc6, 0x14, 0x51, 0x45, 00, 0x15, 0x53, 0x56, + 0xd4, 0xed, 0xf4, 0x5d, 0x2e, 0xee, 0xfe, 0xea, 0x41, 0x15, + 0xb5, 0xb4, 0x4d, 0x2c, 0x8e, 0x7b, 0x2a, 0x8c, 0x9a, 0xb7, + 0x5e, 0x2b, 0xfb, 0x55, 0x78, 0xc4, 0x68, 0x1f, 0xf, 0x86, + 0x93, 0x13, 0xe2, 0xeb, 0x58, 0x93, 0xca, 0xc0, 0xff, 00, + 0x9e, 0x4b, 0x86, 0x73, 0xff, 00, 0xa0, 0x8f, 0xc6, 0xb9, + 0xb1, 0x35, 0x96, 0x1e, 0x8c, 0xaa, 0xbe, 0x88, 0xe4, 0xc5, + 0xd7, 0x58, 0x5a, 0x13, 0xac, 0xfa, 0x2f, 0xf8, 0x63, 0xe4, + 0xcf, 0x12, 0xeb, 0x93, 0xf8, 0xa7, 0xc4, 0x7a, 0x8e, 0xad, + 0x71, 0x8f, 0x3e, 0xfa, 0xe1, 0xe6, 0x60, 0x3a, 0xc, 0x9e, + 00, 0xf6, 0x3, 0x2, 0xbe, 0xc2, 0xfd, 0x9b, 0x3c, 0x23, + 0xff, 00, 0x8, 0xe7, 0x80, 0xa3, 0xb9, 0x91, 0x36, 0xdc, + 0x5e, 0xb1, 0x90, 0xe4, 0x73, 0xb7, 0xb5, 0x7c, 0x91, 0xe0, + 0x6f, 0xf, 0xc9, 0xe2, 0x6f, 0x14, 0x69, 0xda, 0x7c, 0x6a, + 0x5b, 0xcd, 0x95, 0x41, 0xc7, 0xa6, 0x79, 0xaf, 0xd0, 0x8d, + 0x32, 0xc2, 0x2d, 0x2f, 0x4f, 0xb7, 0xb4, 0x85, 0x42, 0x47, + 0xa, 0x4, 0x50, 0x3d, 0x85, 0x7c, 0x6e, 0x43, 0x45, 0xd6, + 0xaf, 0x3c, 0x4c, 0xfa, 0x7e, 0x6c, 0xf8, 0xfe, 0x1d, 0xa0, + 0xea, 0x4e, 0x78, 0xa9, 0xef, 0xfa, 0xbd, 0xcb, 0x54, 0x51, + 0x45, 0x7d, 0xd9, 0xf7, 0x61, 0x45, 0x14, 0x50, 0x1, 0x5f, + 0x98, 0xbf, 0xf0, 0x5b, 0x2f, 0x1d, 0xdc, 0x5a, 0xf8, 0x77, + 0xe1, 0xaf, 0x83, 0x62, 0x25, 0x6d, 0xaf, 0x6e, 0x6e, 0xb5, + 0x59, 0xf0, 0x48, 0xc9, 0x89, 0x52, 0x34, 0x7, 0xd4, 0x7e, + 0xf9, 0xcf, 0xe1, 0x5f, 0xa7, 0x55, 0xf9, 0xe5, 0xff, 00, + 0x5, 0x88, 0xf8, 0x15, 0xab, 0x78, 0xf7, 0xe1, 0x97, 0x86, + 0x3c, 0x79, 0xa2, 0x59, 0xcd, 0x7f, 0x2f, 0x85, 0xa6, 0x9a, + 0x2b, 0xf8, 0x60, 0x42, 0xcc, 0x96, 0x93, 0x5, 0x26, 0x5c, + 0xe, 0x70, 0x8f, 0x1a, 0xe7, 0xd0, 0x31, 0x3d, 0xa8, 0x13, + 0xd8, 0xf8, 0x57, 0xfe, 0x9, 0xbb, 0xf1, 0x4b, 0xc1, 0xff, + 00, 0x8, 0x7f, 0x6a, 0x4d, 0x1f, 0x5d, 0xf1, 0xb5, 0xec, + 0x1a, 0x5e, 0x92, 0xf6, 0x37, 0x36, 0x91, 0xea, 0x17, 0x23, + 0xf7, 0x56, 0xd3, 0xc8, 0xa0, 0x23, 0xb1, 0xfe, 0x10, 0x40, + 0x65, 0xdd, 0xdb, 0x77, 0x3c, 0x57, 0xe8, 0x87, 0xfc, 0x15, + 0x1f, 0xf6, 0x8d, 0xd2, 0x7c, 0x31, 0xfb, 0x2e, 0x36, 0x8b, + 0xe1, 0xed, 0x62, 0xcf, 0x51, 0xbb, 0xf1, 0xb4, 0xc2, 0xc2, + 0x29, 0x6c, 0xae, 0x16, 0x55, 0xfb, 0x2a, 0xe1, 0xe7, 0x70, + 0x54, 0x91, 0x82, 0x36, 0xa7, 0xfd, 0xb4, 0xaf, 0xc4, 0xea, + 0x37, 0x12, 00, 0xc9, 0xc0, 0xe8, 0x2a, 0xac, 0x45, 0xcf, + 0xb5, 0x7f, 0xe0, 0x94, 0x9f, 0xc, 0xb4, 0xcf, 0x13, 0xfe, + 0xd0, 0x57, 0x3e, 0x35, 0xd7, 0xee, 0x6d, 0xac, 0xf4, 0x4f, + 0x5, 0x59, 0x1b, 0xe3, 0x3d, 0xe4, 0x8b, 0x1c, 0x42, 0xe6, + 0x4c, 0xa4, 0x59, 0x66, 0xc0, 0xe0, 0x79, 0x8d, 0xf5, 0x51, + 0x5e, 0xd9, 0xff, 00, 0x5, 0x2f, 0xff, 00, 0x82, 0x80, + 0xf8, 0x77, 0xc6, 0x7e, 0x11, 0xbb, 0xf8, 0x4f, 0xf0, 0xd7, + 0x53, 0x8f, 0x59, 0xb6, 0xbe, 0x64, 0x3a, 0xd6, 0xbd, 0x65, + 0x29, 0x30, 0x6c, 0x56, 0xd, 0xf6, 0x78, 0x98, 0x7d, 0xfc, + 0x90, 0x37, 0x30, 0xf9, 0x71, 0xc7, 0x39, 0x38, 0xfc, 0xc0, + 0x12, 0xba, 0xc6, 0xd1, 0x87, 0x61, 0x1b, 0x10, 0x59, 0x1, + 0xe0, 0x91, 0xd3, 0x22, 0xbd, 0x33, 0xe0, 0x1f, 0xec, 0xe5, + 0xe3, 0x9f, 0xda, 0x43, 0xc6, 0x50, 0x78, 0x7f, 0xc1, 0xba, + 0x4c, 0x97, 0x44, 0xb7, 0xfa, 0x4e, 0xa3, 0x2a, 0x95, 0xb4, + 0xb3, 0x4e, 0xed, 0x2c, 0x98, 0xc0, 0xf6, 0x1d, 0x4f, 0x60, + 0x68, 0xb, 0xf4, 0x3b, 0xbf, 0xd8, 0x3f, 0xf6, 0x70, 0x9f, + 0xf6, 0x92, 0xf8, 0xff, 00, 0xa3, 0x69, 0x33, 0xc2, 0xe7, + 0xc3, 0x7a, 0x53, 0x2e, 0xa7, 0xac, 0x4e, 0x17, 0x2a, 0x21, + 0x46, 0x5, 0x62, 0xcf, 0x4c, 0xc8, 0xd8, 0x5c, 0x7a, 0x16, + 0x3d, 0xab, 0xfa, 0xd, 0x44, 0x58, 0x91, 0x51, 0x14, 0x2a, + 0xa8, 0xc0, 0x3, 0xa0, 0x15, 0xe2, 0xff, 00, 0xb2, 0x8f, + 0xec, 0xb7, 0xe1, 0xaf, 0xd9, 0x53, 0xe1, 0xa4, 0x3e, 0x1b, + 0xd1, 0x7f, 0xd3, 0x35, 0x3b, 0x82, 0x27, 0xd5, 0x75, 0x67, + 0x5c, 0x49, 0x79, 0x3e, 0x31, 0x9f, 0x64, 0x1d, 0x15, 0x7b, + 0xf, 0x72, 0x4d, 0x7b, 0x43, 0xba, 0xc6, 0x8c, 0xec, 0x42, + 0xaa, 0x8c, 0x92, 0x7b, 0xa, 0x96, 0xcb, 0x4a, 0xc7, 0x81, + 0xfe, 0xd2, 0x9e, 0x23, 0x13, 0x5e, 0xe9, 0x9a, 0x24, 0x6f, + 0x91, 0x8, 0x37, 0x33, 0x1, 0xfd, 0xe3, 0xc2, 0x8f, 0xcb, + 0x77, 0xe7, 0x5e, 0x25, 0x5b, 0xbe, 0x39, 0xd7, 0xcf, 0x8a, + 0x3c, 0x5b, 0xaa, 0x6a, 0x79, 0x26, 0x39, 0xa6, 0x3e, 0x5e, + 0x7f, 0xb8, 0x3e, 0x55, 0xfd, 00, 0xac, 0x2a, 0xfc, 0x4b, + 0x33, 0xc4, 0xfd, 0x6f, 0x17, 0x52, 0xaf, 0x4b, 0xe9, 0xe8, + 0xb4, 0x47, 0xc9, 0x62, 0x2a, 0x7b, 0x5a, 0xb2, 0x90, 0x51, + 0x45, 0x15, 0xe6, 0x18, 0x16, 0xec, 0x74, 0x8b, 0xed, 0x50, + 0x39, 0xb3, 0xb2, 0xb8, 0xbb, 0x9, 0x8d, 0xde, 0x44, 0x4c, + 0xfb, 0x73, 0xd3, 0x38, 0x1c, 0x54, 0xd2, 0x78, 0x6f, 0x57, + 0x88, 0x65, 0xf4, 0xab, 0xd4, 0x1e, 0xad, 0x6c, 0xe3, 0xfa, + 0x57, 0xd2, 0x1f, 00, 0x74, 0xf, 0xec, 0x8f, 0x2, 0x47, + 0x74, 0xe9, 0xb6, 0x6d, 0x42, 0x56, 0x9c, 0x92, 0x39, 0xd8, + 0x3e, 0x55, 0xfd, 0x1, 0x3f, 0x8d, 0x7a, 0x55, 0x7d, 0xd6, + 0x13, 0x86, 0xa3, 0x88, 0xc3, 0xc2, 0xac, 0xea, 0x34, 0xe4, + 0xaf, 0x6b, 0x77, 0x3d, 0x8a, 0x58, 0x5, 0x38, 0x29, 0x39, + 0x5a, 0xe7, 0xc3, 0x12, 0xc1, 0x2c, 0x7, 0x12, 0xc6, 0xf1, + 0x9f, 0x47, 0x52, 0x2a, 0x3a, 0xfb, 0x96, 0xe2, 0xce, 0xde, + 0xed, 0xa, 0x4f, 0x4, 0x73, 0x21, 0xfe, 0x19, 0x10, 0x30, + 0xfd, 0x6b, 0x8c, 0xf1, 0x3f, 0xc1, 0xaf, 0xc, 0xf8, 0x8e, + 0xde, 0x40, 0x96, 0x11, 0xe9, 0xb7, 0x44, 0x1d, 0xb7, 0x16, + 0x6a, 0x10, 0x83, 0xee, 0xa3, 0x83, 0xf9, 0x54, 0xd6, 0xe1, + 0x6a, 0xb1, 0x57, 0xa3, 0x51, 0x3f, 0x26, 0xad, 0xfe, 0x62, + 0x9e, 0x5d, 0x24, 0xbd, 0xd9, 0x5c, 0xf9, 0x36, 0x8a, 0xd4, + 0xf1, 0x3f, 0x87, 0xae, 0x7c, 0x2b, 0xaf, 0x5e, 0x69, 0x57, + 0x78, 0x33, 0x5b, 0x3e, 0xd2, 0xcb, 0xd1, 0x81, 0x19, 0xc, + 0x3e, 0xa0, 0x83, 0x59, 0x75, 0xf1, 0x53, 0x84, 0xa9, 0xc9, + 0xc2, 0x4a, 0xcd, 0x68, 0x79, 0x2d, 0x34, 0xec, 0xc2, 0x8a, + 0x28, 0xa8, 0x11, 0xe9, 0xbf, 00, 0x3c, 0x49, 0x36, 0x93, + 0xe3, 0x68, 0xf4, 0xed, 0xc7, 0xec, 0xba, 0x8a, 0x32, 0x32, + 0x76, 0xe, 0xa0, 0xb2, 0x9f, 0xd0, 0x8f, 0xc6, 0xbe, 0x9e, + 0xaf, 0x92, 0xbe, 0xb, 0xda, 0x3d, 0xdf, 0xc4, 0xad, 0x1b, + 0x68, 0x24, 0x46, 0xcf, 0x23, 0x11, 0xd8, 0x4, 0x6f, 0xfe, + 0xb5, 0x7d, 0x6b, 0x5f, 0xa9, 0xf0, 0xcc, 0xe7, 0x2c, 0x13, + 0x52, 0xd9, 0x49, 0xdb, 0xee, 0x4c, 0xfa, 0x2c, 0xbd, 0xb7, + 0x49, 0xa7, 0xdc, 0xa5, 0xad, 0xea, 0x71, 0xe8, 0xda, 0x3d, + 0xed, 0xfc, 0xa7, 0x11, 0xdb, 0x42, 0xf2, 0x9c, 0xff, 00, + 0xb2, 0x9, 0xaf, 0x89, 0xae, 0xae, 0x64, 0xbd, 0xb9, 0x9a, + 0xe2, 0x56, 0xdd, 0x2c, 0xae, 0x64, 0x76, 0xf5, 0x24, 0xe4, + 0xd7, 0xda, 0x3e, 0x28, 0xf0, 0xf4, 0x3e, 0x2a, 0xd0, 0xee, + 0x74, 0xbb, 0x89, 0xa6, 0x82, 0xb, 0x80, 0x3, 0xbc, 0x4, + 0x6, 0xc0, 0x20, 0xe3, 0x90, 0x7d, 0x2b, 0xcd, 0xa4, 0xfd, + 0x9a, 0xb4, 0x16, 0xfb, 0x9a, 0x9e, 0xa0, 0xbf, 0x52, 0x87, + 0xff, 00, 0x65, 0xa8, 0xcf, 0x72, 0xfc, 0x5e, 0x61, 0x28, + 0x2a, 0x9, 0x72, 0xc6, 0xfd, 0x7a, 0xb1, 0x63, 0x28, 0x55, + 0xac, 0xd7, 0x22, 0xd1, 0x1f, 0x39, 0x51, 0x5f, 0x42, 0x49, + 0xfb, 0x33, 0x69, 0x87, 0xee, 0x6b, 0x57, 0x6b, 0xfe, 0xf4, + 0x6a, 0x6a, 0xb4, 0x9f, 0xb3, 0x1c, 0x7, 0xee, 0x6b, 0xf2, + 0xf, 0xf7, 0xad, 0x81, 0xff, 00, 0xd9, 0xab, 0xe4, 0x9f, + 0xf, 0xe6, 0x2b, 0xec, 0x7e, 0x2b, 0xfc, 0xcf, 0x33, 0xea, + 0x55, 0xfb, 0x7e, 0x27, 0x82, 0x51, 0x5e, 0x9b, 0xf1, 0x17, + 0xe0, 0xd2, 0x78, 0x3, 0x42, 0x1a, 0x8b, 0x6b, 0x3f, 0x6b, + 0x2f, 0x32, 0xc2, 0x90, 0xfd, 0x9f, 0x61, 0x62, 0x72, 0x7a, + 0xee, 0x3d, 00, 0x3d, 0xab, 0xcc, 0xab, 0xc7, 0xc4, 0xe1, + 0x6b, 0x60, 0xea, 0x7b, 0x2a, 0xca, 0xcf, 0xe4, 0xff, 00, + 0x23, 0x96, 0xa5, 0x39, 0x52, 0x97, 0x2c, 0xd6, 0xa1, 0x45, + 0x14, 0x57, 0x21, 0x98, 0x51, 0x45, 0x7a, 0x44, 0x1f, 00, + 0x7c, 0x55, 0x73, 0x6b, 0xd, 0xc4, 0x6b, 0x66, 0x56, 0x54, + 0x59, 0x2, 0x99, 0xc8, 0x20, 0x11, 0x9c, 0x1e, 0x3a, 0xd7, + 0x55, 0xc, 0x2d, 0x7c, 0x4d, 0xfd, 0x8c, 0x1c, 0xad, 0xbd, + 0x8d, 0x21, 0x4e, 0x75, 0x3e, 0x5, 0x73, 0xcd, 0xe8, 0xaf, + 0x46, 0x93, 0xe0, 0xf, 0x8c, 0x13, 0xa5, 0xa5, 0xb3, 0xff, + 00, 0xbb, 0x72, 0xb5, 0x56, 0x5f, 0x81, 0xfe, 0x32, 0x8b, + 0xa6, 0x94, 0x1f, 0xfd, 0xcb, 0x88, 0xff, 00, 0xf8, 0xaa, + 0xe8, 0x79, 0x6e, 0x35, 0x6f, 0x46, 0x5f, 0x73, 0x2f, 0xd8, + 0x55, 0x5f, 0x65, 0xfd, 0xc7, 0x7, 0x5e, 0xd3, 0xfb, 0x34, + 0x69, 0x3e, 0x6e, 0xaf, 0xab, 0xea, 0x4c, 0xbc, 0x43, 0xa, + 0xc0, 0x8d, 0xee, 0xc7, 0x27, 0xf4, 0x51, 0xf9, 0xd7, 0x12, + 0xff, 00, 0x7, 0x3c, 0x64, 0x9d, 0x74, 0x29, 0x8f, 0xfb, + 0xb2, 0x46, 0x7f, 0xf6, 0x6a, 0xf7, 0x9f, 0x82, 0x9e, 0x12, + 0xb9, 0xf0, 0x9f, 0x83, 0x84, 0x77, 0xd0, 0x1b, 0x6b, 0xeb, + 0x89, 0x9e, 0x59, 0x63, 0x6e, 0xab, 0xfc, 0x2a, 0xf, 0xe0, + 0x33, 0xf8, 0xd7, 0xb7, 0x91, 0xe0, 0x2b, 0xac, 0x74, 0x67, + 0x56, 0xd, 0x28, 0xdd, 0xea, 0x9a, 0xf2, 0xfd, 0x4e, 0xbc, + 0x1d, 0x19, 0xfb, 0x64, 0xe4, 0xad, 0x63, 0xbf, 0xa2, 0x8a, + 0xf3, 0x4f, 0x8a, 0xff, 00, 0x17, 0xa0, 0xf0, 0x54, 0x6d, + 0xa7, 0x69, 0xfb, 0x6e, 0x35, 0xa7, 0x5c, 0xf3, 0xca, 0x40, + 0xf, 0x76, 0xf5, 0x3e, 0x83, 0xf3, 0xf7, 0xfd, 0x27, 0x13, + 0x89, 0xa5, 0x84, 0xa4, 0xea, 0xd6, 0x76, 0x48, 0xf7, 0xea, + 0x54, 0x8d, 0x28, 0xf3, 0x49, 0xe8, 0x74, 0xde, 0x33, 0xf8, + 0x83, 0xa3, 0xf8, 0x1a, 0xd3, 0xcc, 0xd4, 0x2e, 0x33, 0x70, + 0xcb, 0x98, 0xad, 0x63, 0xe6, 0x59, 0x3e, 0x83, 0xb0, 0xf7, + 0x3c, 0x57, 0xcf, 0xde, 0x32, 0xf8, 0xe3, 0xaf, 0xf8, 0xa3, + 0x7c, 0x36, 0xaf, 0xfd, 0x91, 0x62, 0x4f, 0xfa, 0xbb, 0x66, + 0x3e, 0x63, 0xf, 0xf6, 0x9f, 0xaf, 0xe5, 0x8a, 0xe1, 0x35, + 0x3d, 0x4e, 0xef, 0x59, 0xbd, 0x96, 0xf2, 0xfa, 0xe2, 0x4b, + 0xab, 0x99, 0x4e, 0x5e, 0x49, 0xe, 0x49, 0xff, 00, 0x3e, + 0x95, 0x56, 0xbf, 0x2f, 0xcc, 0x33, 0xec, 0x46, 0x31, 0xb8, + 0x53, 0x7c, 0x90, 0xec, 0xb7, 0x7e, 0xac, 0xf9, 0xda, 0xf8, + 0xca, 0x95, 0x74, 0x8e, 0x88, 0x57, 0x76, 0x91, 0x8b, 0x33, + 0x16, 0x62, 0x72, 0x49, 0x39, 0x26, 0x92, 0x8a, 0x2b, 0xe6, + 0x4e, 00, 0xa2, 0x8a, 0x96, 0xde, 0xd2, 0x7b, 0xc7, 0xd9, + 0x4, 0x32, 0x4e, 0xdf, 0xdd, 0x8d, 0xb, 0x1f, 0xd2, 0x9a, + 0x4d, 0xbb, 0x20, 0x22, 0xa2, 0xb5, 0x47, 0x84, 0xb5, 0xc2, + 0x32, 0x34, 0x5d, 0x47, 0x1e, 0xbf, 0x64, 0x93, 0xfc, 0x2a, + 0x95, 0xd6, 0x9f, 0x75, 0x62, 0x71, 0x73, 0x6d, 0x35, 0xb9, + 0xf4, 0x96, 0x32, 0xbf, 0xce, 0xae, 0x54, 0xe7, 0x15, 0x79, + 0x45, 0xaf, 0x90, 0xdc, 0x5a, 0xdd, 0x15, 0xe8, 0xa2, 0x8a, + 0xcc, 0x41, 0x57, 0x34, 0xad, 0x66, 0xfb, 0x43, 0xba, 0x5b, + 0x9d, 0x3e, 0xee, 0x6b, 0x39, 0xd4, 0xe7, 0x7c, 0x2e, 0x57, + 0x3f, 0x5f, 0x5f, 0xa1, 0xaa, 0x74, 0x55, 0x46, 0x4e, 0x2f, + 0x9a, 0x2e, 0xcc, 0x13, 0x6b, 0x54, 0x7b, 0xef, 0xc3, 0xef, + 0xda, 0x9, 0x2e, 0xe5, 0x8e, 0xc7, 0xc4, 0xc1, 0x20, 0x73, + 0x85, 0x5b, 0xf8, 0xc6, 0x14, 0x9f, 0xf6, 0xc7, 0x6f, 0xa8, + 0xe3, 0xd8, 0x57, 0xb6, 0x47, 0x22, 0x4d, 0x1a, 0xc9, 0x1b, + 0x7, 0x46, 0x19, 0x56, 0x53, 0x90, 0x47, 0xa8, 0x35, 0xf0, + 0xb5, 0x7a, 0xc7, 0xc1, 0x9f, 0x8b, 0x12, 0x78, 0x76, 0xf2, + 0x1d, 0x17, 0x55, 0x98, 0xbe, 0x93, 0x2b, 0x6d, 0x8a, 0x47, + 0x3f, 0xf1, 0xee, 0xc7, 0xa7, 0x3f, 0xdd, 0x3f, 0xa7, 0xe7, + 0x5f, 0x77, 0x94, 0x67, 0xf2, 0xe6, 0x58, 0x7c, 0x63, 0xba, + 0x7b, 0x4b, 0xfc, 0xff, 00, 0xcf, 0xef, 0x3d, 0x9c, 0x2e, + 0x35, 0xdd, 0x42, 0xaf, 0xde, 0x7d, 0x27, 0x45, 0x20, 0x20, + 0x8c, 0x8e, 0x41, 0xa5, 0xaf, 0xd0, 0xcf, 0x70, 0x28, 0xa2, + 0xaa, 0xea, 0x7a, 0x9d, 0xb6, 0x8d, 0xa7, 0xcf, 0x7b, 0x79, + 0x32, 0xc1, 0x6d, 0x2, 0x17, 0x92, 0x46, 0xe8, 00, 0xa4, + 0xda, 0x8a, 0xbb, 0xd8, 0x4d, 0xdb, 0x56, 0x59, 0x66, 0x8, + 0xa5, 0x98, 0x80, 0x7, 0x24, 0x9e, 0xd5, 0xe6, 0xfe, 0x30, + 0xf8, 0xed, 0xa0, 0x78, 0x6f, 0x7c, 0x36, 0x4d, 0xfd, 0xb1, + 0x7a, 0x38, 0xd9, 0x6e, 0xd8, 0x8d, 0x4f, 0xbb, 0xf4, 0xfc, + 0xb3, 0x5e, 0x45, 0xf1, 0x27, 0xe3, 0x16, 0xa1, 0xe3, 0x29, + 0xe5, 0xb4, 0xb1, 0x79, 0x2c, 0x34, 0x60, 0x70, 0x22, 0x53, + 0x87, 0x98, 0x7a, 0xb9, 0x1d, 0xbf, 0xd9, 0xe9, 0xf5, 0xaf, + 0x3a, 0xaf, 0x80, 0xcc, 0x78, 0x95, 0xa6, 0xe9, 0xe0, 0xd7, + 0xfd, 0xbc, 0xff, 00, 0x45, 0xfe, 0x7f, 0x71, 0xe2, 0xd7, + 0xc7, 0xbb, 0xf2, 0xd2, 0xfb, 0xcf, 0x47, 0xf1, 0x7, 0xc7, + 0xbf, 0x14, 0x6b, 0x3b, 0x92, 0xda, 0x68, 0xb4, 0xa8, 0x4f, + 0xf0, 0xda, 0xaf, 0xcd, 0xff, 00, 0x7d, 0x36, 0x4f, 0xe5, + 0x8a, 0xe1, 0x6f, 0xf5, 0xad, 0x43, 0x54, 0x62, 0xd7, 0x97, + 0xd7, 0x37, 0x64, 0xf7, 0x9a, 0x56, 0x7f, 0xe6, 0x6a, 0x95, + 0x15, 0xf1, 0x75, 0xf1, 0x98, 0x8c, 0x4b, 0xbd, 0x69, 0xb7, + 0xf3, 0xfd, 0xf, 0x26, 0x75, 0x67, 0x53, 0xe2, 0x77, 0xa, + 0x28, 0xa2, 0xb8, 0xcc, 0xc2, 0x8a, 0x28, 0xa0, 0x2, 0x8a, + 0x28, 0xa0, 0xb, 0x76, 0x7a, 0xbd, 0xf6, 0x9c, 0xc1, 0xad, + 0x6f, 0x6e, 0x2d, 0x88, 0xef, 0xc, 0xac, 0x9f, 0xc8, 0xd7, + 0x5b, 0xa2, 0x7c, 0x68, 0xf1, 0x6e, 0x8a, 0x55, 0x57, 0x53, + 0x6b, 0xd8, 0xc7, 0x1e, 0x5d, 0xe2, 0x89, 0x33, 0xf8, 0xfd, + 0xef, 0xd6, 0xb8, 0x7a, 0xdb, 0xf0, 0x4e, 0x96, 0x75, 0xaf, + 0x17, 0x68, 0xf6, 0x41, 0x77, 0x9, 0x6e, 0xa3, 0xc, 0x3f, + 0xd9, 0x7, 0x2d, 0xfa, 0x3, 0x5d, 0xd8, 0x6a, 0xf8, 0x88, + 0x54, 0x8c, 0x68, 0xcd, 0xa6, 0xdd, 0xb4, 0x66, 0xb4, 0xe7, + 0x35, 0x24, 0xa0, 0xec, 0x7d, 0x8d, 0xa5, 0xcb, 0x71, 0x3e, + 0x9b, 0x6b, 0x25, 0xda, 0xaa, 0x5d, 0x3c, 0x4a, 0xd2, 0xaa, + 0xc, 00, 0xc4, 0xc, 0x81, 0xf8, 0xd5, 0x9c, 0x73, 0x9a, + 0x5a, 0x2b, 0xf7, 0x14, 0xac, 0x92, 0x3e, 0xbd, 0x5, 0x14, + 0x51, 0x4c, 0x61, 0x58, 0xfe, 0x2e, 0x97, 0xca, 0xf0, 0xed, + 0xeb, 0x74, 0xf9, 0xd, 0x6c, 0x57, 0x33, 0xf1, 0x12, 0x6f, + 0x27, 0xc2, 0xb7, 0x7d, 0xb2, 0x31, 0x58, 0xd6, 0x7c, 0xb4, + 0xe4, 0xfc, 0x8c, 0xea, 0x3b, 0x41, 0xb3, 0xe1, 0x4f, 0x88, + 0x13, 0x79, 0xde, 0x22, 0xbb, 0x6f, 0xf6, 0x8d, 0x78, 0x7, + 0xc6, 0x8b, 0x8f, 0x2f, 0x47, 0x9b, 0x9f, 0xe1, 0x35, 0xee, + 0x5e, 0x2e, 0x97, 0xcd, 0xd6, 0x6f, 0x1b, 0xfd, 0xb3, 0x5f, + 0x3c, 0x7c, 0x78, 0xb9, 0xf2, 0xb4, 0x6b, 0x9f, 0x68, 0xcf, + 0xf2, 0xaf, 0xcd, 0xb2, 0xc5, 0xcd, 0x5e, 0xfe, 0xa7, 0xe2, + 0x18, 0xbf, 0xde, 0xe3, 0xe9, 0xc7, 0xbc, 0xd7, 0xe6, 0x7e, + 0x94, 0xfc, 0xc, 0xf0, 0x98, 0x5f, 0x82, 0x7f, 0xf, 0x84, + 0x90, 0xb0, 0x90, 0x78, 0x7b, 0x4f, 0xd, 0x91, 0xce, 0x7e, + 0xcd, 0x1e, 0x68, 0xaf, 0x59, 0xf8, 0x75, 0x66, 0x2c, 0xfe, + 0x1f, 0x78, 0x62, 0xdc, 0xc6, 0x10, 0xc5, 0xa5, 0xda, 0xc7, + 0xb7, 0x1d, 0x31, 0x12, 0x8c, 0x51, 0x5f, 0xa6, 0x24, 0x7e, + 0xe0, 0xa3, 0xa1, 0xd1, 0xd1, 0x45, 0x15, 0x65, 0x85, 0x14, + 0x51, 0x40, 0x5, 0x7c, 0x4d, 0xfb, 0x4b, 0xf8, 0xc4, 0xf8, + 0xa3, 0xe2, 0x65, 0xcd, 0xac, 0x6e, 0x1a, 0xd3, 0x49, 0x51, + 0x69, 0x1e, 0x31, 0x8d, 0xfd, 0x5c, 0xe4, 0x7b, 0x9c, 0x7e, + 0x15, 0xf5, 0xdf, 0x8e, 0xfc, 0x51, 0xf, 0x82, 0xfc, 0x21, + 0xaa, 0xeb, 0x33, 0x9f, 0x96, 0xd2, 0x6, 0x75, 0x5c, 0xe3, + 0x73, 0xe3, 0xa, 0xa3, 0xdc, 0x9c, 0x57, 0xe7, 0x9b, 0xcb, + 0x3e, 0xa5, 0x7a, 0xf3, 0x4c, 0xc6, 0x5b, 0x9b, 0x89, 0xb, + 0xbb, 0x1e, 0xac, 0xcc, 0x72, 0x4f, 0xe6, 0x6b, 0xe4, 0x78, + 0x83, 0x13, 0xcb, 0x4e, 0x34, 0x17, 0x5d, 0x5f, 0xa2, 0x3e, + 0x33, 0x88, 0xf1, 0x36, 0x84, 0x30, 0xd1, 0xde, 0x5a, 0xbf, + 0x45, 0xb7, 0xe3, 0xf9, 0x1e, 0xfb, 0xfb, 0x27, 0x78, 0x3f, + 0xed, 0xba, 0xdd, 0xe6, 0xb5, 0x32, 0xe6, 0x3b, 0x65, 0xdb, + 0x1e, 0x47, 0xf1, 0x1a, 0xfa, 0xb6, 0xbc, 0xff, 00, 0xe0, + 0x77, 0x85, 0x7, 0x85, 0x7e, 0x1f, 0xe9, 0xf1, 0x32, 0x6d, + 0x9e, 0x75, 0xf3, 0xa4, 0xfa, 0x9a, 0xf4, 0xa, 0xf5, 0xf2, + 0xac, 0x3f, 0xd5, 0xb0, 0x90, 0x8b, 0xdd, 0xea, 0xfe, 0x67, + 0xd0, 0x65, 0xb8, 0x7f, 0xaa, 0xe1, 0x61, 0xe, 0xbb, 0xbf, + 0x98, 0x51, 0x45, 0x15, 0xeb, 0x9e, 0x98, 0x51, 0x45, 0x14, + 00, 0x53, 0x26, 0x86, 0x3b, 0x98, 0x64, 0x86, 0x68, 0xd6, + 0x58, 0xa4, 0x52, 0xae, 0x8e, 0x32, 0xac, 0xf, 0x4, 0x11, + 0xdc, 0x56, 0x5f, 0x8a, 0xfc, 0x5b, 0xa3, 0x78, 0x1b, 0xc3, + 0xf7, 0xba, 0xe7, 0x88, 0x35, 0x3b, 0x5d, 0x1f, 0x48, 0xb2, + 0x8c, 0xcb, 0x71, 0x7b, 0x79, 0x20, 0x8e, 0x38, 0xd4, 0x77, + 0x24, 0xd7, 0xe7, 0xf7, 0xc6, 0xdf, 0xf8, 0x2c, 0x9f, 0x82, + 0xfc, 0x31, 0x3c, 0xd6, 0x1f, 0xd, 0xbc, 0x39, 0x73, 0xe3, + 0xb, 0x84, 0x3b, 0x7f, 0xb4, 0xb5, 0x16, 0x36, 0x96, 0x9f, + 0x55, 0x5c, 0x19, 0x1f, 0xf1, 0xb, 0x40, 0x1e, 0x85, 0xf1, + 0x93, 0xfe, 0x9, 0x37, 0xf0, 0x6b, 0xe2, 0x76, 0xa3, 0x73, + 0xa9, 0xe8, 0x9f, 0xda, 0x3e, 0x3, 0xd4, 0x6e, 0x1c, 0xc9, + 0x20, 0xd2, 0x1d, 0x5e, 0xd4, 0xb1, 0xeb, 0xfb, 0x97, 0x4, + 0x2f, 0xd1, 0xa, 0x8a, 0xf0, 0xd9, 0xbf, 0xe0, 0x88, 0xb0, + 0xfd, 0xb3, 0x31, 0x7c, 0x58, 0x90, 0x5a, 0x67, 0xa3, 0xe8, + 0xa0, 0xc9, 0x8f, 0xa8, 0x9b, 0x15, 0xe2, 0x1a, 0xa7, 0xfc, + 0x16, 0xf, 0xe3, 0xc5, 0xf4, 0xcc, 0xd6, 0xd0, 0x78, 0x57, + 0x4e, 0x8c, 0xfd, 0xd4, 0x87, 0x4c, 0x76, 0xc7, 0xe2, 0xf2, + 0xb6, 0x6b, 0xed, 0xf, 0xf8, 0x26, 0xc7, 0xed, 0x35, 0xf1, + 0x77, 0xf6, 0xa3, 0x93, 0xc5, 0xba, 0xcf, 0x8e, 0x2e, 0xb4, + 0xb6, 0xf0, 0xde, 0x91, 0xe5, 0x5a, 0x5b, 0x8b, 0x1b, 0x11, + 0xb, 0xcb, 0x74, 0xff, 00, 0x33, 0x65, 0xb2, 0x78, 0x54, + 0x3, 0x81, 0xfd, 0xf1, 0x4f, 0x52, 0x74, 0x65, 0xf, 0x87, + 0x1f, 0xf0, 0x47, 0x3f, 0x84, 0x5e, 0x16, 0xb8, 0x4b, 0x8f, + 0x13, 0xeb, 0x1a, 0xef, 0x8c, 0xa4, 0x52, 0xf, 0x91, 0x2c, + 0xab, 0x67, 0x6e, 0x48, 0xf5, 0x58, 0xfe, 0x7f, 0xfc, 0x7e, + 0xbe, 0xd5, 0xf0, 0x27, 0xc3, 0xef, 0xd, 0xfc, 0x31, 0xf0, + 0xe5, 0xb6, 0x81, 0xe1, 0x4d, 0x12, 0xcb, 0x40, 0xd1, 0xed, + 0x86, 0x23, 0xb4, 0xb1, 0x88, 0x46, 0x83, 0xd4, 0x9c, 0x75, + 0x27, 0xb9, 0x39, 0x26, 0xbc, 0x43, 0xc5, 0x7f, 0xf0, 0x50, + 0xef, 0x80, 0xbe, 0x6, 0xf1, 0x76, 0xaf, 0xe1, 0x8d, 0x7b, + 0xc6, 0xaf, 0xa6, 0x6b, 0x5a, 0x55, 0xd4, 0x96, 0x77, 0x96, + 0xd2, 0xe9, 0x77, 0x67, 0xcb, 0x95, 0x1b, 0x6b, 0xd, 0xc2, + 0x22, 0xa7, 0x91, 0xd4, 0x1c, 0x1a, 0xf5, 0xbf, 0x84, 0xbf, + 0x19, 0xbc, 0x1d, 0xf1, 0xcf, 0xc2, 0xed, 0xe2, 0x2f, 0x3, + 0xeb, 0x51, 0xeb, 0xba, 0x3a, 0xdc, 0x35, 0xab, 0x5c, 0xc7, + 0x1b, 0xc6, 0x4, 0x8a, 0x1, 0x65, 0xc3, 0xa8, 0x3c, 0x6, + 0x1d, 0xbb, 0xd2, 0x19, 0xda, 0xd7, 0x11, 0xf1, 0x93, 0xc4, + 0x43, 0xc3, 0xbe, 0x1, 0xd4, 0x59, 0x5f, 0x6c, 0xf7, 0x4b, + 0xf6, 0x58, 0xb9, 0xe7, 0x2f, 0xc1, 0xfc, 0x97, 0x71, 0xae, + 0xde, 0xbe, 0x76, 0xfd, 0xa4, 0x7c, 0x43, 0xf6, 0xcd, 0x7e, + 0xc3, 0x48, 0x8d, 0xf2, 0x96, 0x91, 0x19, 0x64, 0x3, 0xfb, + 0xef, 0xd3, 0xf2, 00, 0x7e, 0x75, 0xe2, 0xe7, 0x18, 0x9f, + 0xaa, 0xe0, 0xa7, 0x35, 0xbb, 0xd1, 0x7a, 0xbf, 0xea, 0xe7, + 0x2e, 0x2a, 0xa7, 0xb3, 0xa4, 0xdf, 0xc8, 0xf1, 0xda, 0x28, + 0xa2, 0xbf, 0x19, 0x3e, 0x54, 0x2a, 0xe6, 0x8f, 0xa6, 0x49, + 0xac, 0xea, 0xd6, 0x76, 0x10, 0x82, 0x65, 0xb9, 0x99, 0x22, + 0x5c, 0x76, 0xdc, 0x40, 0xcd, 0x53, 0xaf, 0x44, 0xf8, 0x18, + 0x9a, 0x64, 0x3e, 0x33, 0xfb, 0x7e, 0xa9, 0x79, 0x6d, 0x67, + 0x15, 0x9c, 0x4c, 0xf1, 0x1b, 0x89, 0x42, 0x6, 0x90, 0xfc, + 0xa3, 0x19, 0xeb, 0x80, 0x58, 0xfe, 0x55, 0xd7, 0x84, 0xa2, + 0xb1, 0x18, 0x88, 0x52, 0x6e, 0xc9, 0xbd, 0x7d, 0x3a, 0x9a, + 0x52, 0x8f, 0x3c, 0xd4, 0x59, 0xf4, 0xfe, 0x9f, 0x63, 0x16, + 0x99, 0x61, 0x6f, 0x69, 0x2, 0xec, 0x86, 0x8, 0xd6, 0x24, + 0x51, 0xd8, 0x1, 0x81, 0x56, 0x2b, 0x2a, 0x3f, 0x16, 0x68, + 0x93, 0x7d, 0xcd, 0x5e, 0xc5, 0xff, 00, 0xdd, 0xb9, 0x43, + 0xfd, 0x6a, 0x43, 0xe2, 0x4d, 0x25, 0x46, 0x4e, 0xa9, 0x66, + 0x7, 0xaf, 0x9e, 0x9f, 0xe3, 0x5f, 0xb7, 0xc6, 0xa5, 0x24, + 0xac, 0xa4, 0xad, 0xea, 0x7d, 0x72, 0x94, 0x6d, 0xa3, 0x34, + 0x69, 0x9, 0xa, 0x9, 0x27, 00, 0x72, 0x49, 0xae, 0x5b, + 0x55, 0xf8, 0xa5, 0xe1, 0x5d, 0x1a, 0x36, 0x69, 0xf5, 0xbb, + 0x57, 0x23, 0xf8, 0x20, 0x7f, 0x35, 0xbf, 0x25, 0xcd, 0x78, + 0xf7, 0xc4, 0x9f, 0x8f, 0x12, 0x6b, 0xf6, 0xb2, 0xe9, 0x9a, + 0xa, 0x49, 0x69, 0x67, 0x20, 0x29, 0x2d, 0xd4, 0x9c, 0x49, + 0x22, 0x9e, 0xa1, 0x47, 0xf0, 0x8f, 0x7e, 0xbf, 0x4a, 0xf3, + 0x71, 0x99, 0xb6, 0x13, 0x7, 0x6, 0xe5, 0x34, 0xdf, 0x64, + 0xee, 0xcc, 0x2a, 0xe2, 0x69, 0xd2, 0x57, 0x6e, 0xec, 0xe2, + 0x3e, 0x27, 0x78, 0x82, 0x2f, 0x13, 0xf8, 0xe7, 0x55, 0xbf, + 0x80, 0x83, 0x6e, 0xd2, 0x8, 0xe3, 0x61, 0xfc, 0x4a, 0x80, + 0x28, 0x3f, 0x8e, 0x33, 0xf8, 0xd7, 0x2d, 0x45, 0x15, 0xf8, + 0xed, 0x6a, 0xb2, 0xaf, 0x52, 0x55, 0x65, 0xbc, 0x9b, 0x7f, + 0x79, 0xf2, 0xd2, 0x93, 0x9c, 0x9c, 0x9f, 0x50, 0xa2, 0x8a, + 0xe9, 0x3c, 0x7, 0xe0, 0x6b, 0xdf, 0x1e, 0x6b, 0x69, 0x65, + 0x6a, 0xc, 0x70, 0x2f, 0xcd, 0x3d, 0xc1, 0x1f, 0x2c, 0x49, + 0xfe, 0x27, 0xb0, 0xa5, 0x4a, 0x94, 0xeb, 0xcd, 0x53, 0xa6, + 0xae, 0xd8, 0x46, 0x2e, 0x6d, 0x46, 0x3b, 0x9e, 0xab, 0xfb, + 0x36, 0xf8, 0x58, 0xa4, 0x57, 0xfa, 0xfc, 0xc8, 0x41, 0x7f, + 0xf4, 0x6b, 0x72, 0x47, 0x51, 0xc1, 0x72, 0x3f, 0x1c, 0xf, + 0xc0, 0xd7, 0xb9, 0x55, 0x3d, 0x23, 0x4a, 0xb6, 0xd0, 0xf4, + 0xcb, 0x6b, 0xb, 0x38, 0xc4, 0x56, 0xd6, 0xf1, 0x88, 0xd1, + 0x47, 0xa0, 0xfe, 0xb5, 0x72, 0xbf, 0x6a, 0xcb, 0xf0, 0x8b, + 0x3, 0x86, 0x85, 0x5, 0xba, 0xdf, 0xd7, 0xa9, 0xf5, 0x94, + 0x29, 0x7b, 0x1a, 0x6a, 0x1, 0x45, 0x14, 0x57, 0xa2, 0x6e, + 0x14, 0x51, 0x45, 00, 0x7c, 0xf7, 0xfb, 0x4a, 0xeb, 0xa6, + 0x7d, 0x67, 0x4c, 0xd2, 0x11, 0xbe, 0x4b, 0x78, 0x8d, 0xc3, + 0x8f, 0xf6, 0x98, 0xe0, 0x7e, 0x41, 0x4f, 0xe7, 0x5e, 0x31, + 0x5d, 0x3f, 0xc4, 0xcd, 0x77, 0xfe, 0x12, 0x3f, 0x1c, 0xea, + 0xf7, 0x81, 0xb7, 0x45, 0xe7, 0x18, 0xa3, 0x3f, 0xec, 0x27, + 0xca, 0x3f, 0x96, 0x7f, 0x1a, 0xe6, 0x2b, 0xf1, 0x3c, 0xcf, + 0x11, 0xf5, 0x9c, 0x65, 0x4a, 0x8b, 0x6b, 0xe9, 0xe8, 0xb4, + 0x47, 0xc9, 0x62, 0x27, 0xed, 0x2a, 0xca, 0x41, 0x45, 0x14, + 0x57, 0x96, 0x73, 0x9b, 0x3e, 0xd, 0xd0, 0xcf, 0x89, 0x3c, + 0x55, 0xa5, 0xe9, 0xb8, 0xca, 0xdc, 0x4e, 0xaa, 0xff, 00, + 0xee, 0xe, 0x5b, 0xf4, 0x6, 0xbe, 0xd1, 0x55, 0xa, 0xa0, + 0x1, 0x80, 0x6, 00, 0xaf, 0x9a, 0xff, 00, 0x67, 0x4d, + 0x18, 0xdf, 0x78, 0xce, 0x7b, 0xf6, 0x5c, 0xc7, 0x63, 0x6e, + 0xc4, 0x1f, 0xf6, 0xdf, 0xe5, 0x1f, 0xa6, 0xea, 0xfa, 0x56, + 0xbf, 0x50, 0xe1, 0x8a, 0x1e, 0xcf, 0xb, 0x2a, 0xaf, 0x79, + 0x3f, 0xc1, 0x7f, 0xc1, 0xb9, 0xf4, 0x19, 0x7c, 0x2d, 0x4d, + 0xcb, 0xb8, 0x51, 0x45, 0x15, 0xf6, 0x7, 0xaa, 0x14, 0x51, + 0x55, 0xb5, 0x1d, 0x42, 0xd, 0x2a, 0xc2, 0xe2, 0xf6, 0xe5, + 0xc4, 0x76, 0xf6, 0xf1, 0xb4, 0xb2, 0x39, 0xec, 0xa0, 0x64, + 0xd2, 0x6d, 0x45, 0x5d, 0x83, 0x76, 0xd4, 0xe3, 0x3e, 0x2d, + 0x7c, 0x47, 0x4f, 0x1, 0x68, 0xaa, 0xb6, 0xfb, 0x5f, 0x55, + 0xba, 0x5, 0x60, 0x43, 0xce, 0xc1, 0xdd, 0xc8, 0xf4, 0x1d, + 0xbd, 0x4d, 0x7c, 0xab, 0x73, 0x73, 0x2d, 0xe5, 0xc4, 0xb3, + 0xcf, 0x23, 0x4b, 0x34, 0xac, 0x5d, 0xe4, 0x73, 0x92, 0xc4, + 0xf5, 0x26, 0xb6, 0x3c, 0x6d, 0xe2, 0xa9, 0xfc, 0x65, 0xe2, + 0x4b, 0xcd, 0x52, 0x72, 0x42, 0xc8, 0xdb, 0x62, 0x8c, 0xff, + 00, 0xcb, 0x38, 0xc7, 0xdd, 0x5f, 0xcb, 0xf5, 0x26, 0xb0, + 0xab, 0xf1, 0xdc, 0xdf, 0x32, 0x96, 0x61, 0x5d, 0xb4, 0xfd, + 0xc5, 0xb2, 0xfd, 0x7e, 0x67, 0xcb, 0x62, 0x6b, 0xba, 0xf3, + 0xf2, 0x5b, 0x5, 0x14, 0x51, 0x5e, 0x11, 0xc6, 0x15, 0xa7, + 0xe1, 0xdf, 0xe, 0x6a, 0x1e, 0x2a, 0xd5, 0x22, 0xb0, 0xd3, + 0x6d, 0xda, 0x79, 0xdc, 0xf6, 0xfb, 0xa8, 0x3f, 0xbc, 0xc7, + 0xb0, 0xf7, 0xa8, 0x34, 0x7d, 0x22, 0xeb, 0x5e, 0xd4, 0xed, + 0xb4, 0xfb, 0x28, 0x8c, 0xd7, 0x57, 0xe, 0x11, 0x10, 0x7a, + 0xfb, 0xfb, 0xe, 0xb5, 0xf5, 0xc7, 0xc3, 0xff, 00, 0x1, + 0xd9, 0x78, 0xb, 0x45, 0x5b, 0x4b, 0x71, 0xbe, 0xe6, 0x40, + 0x1a, 0xe6, 0xe0, 0xf5, 0x91, 0xf1, 0xfa, 0x1, 0xd8, 0x57, + 0xbf, 0x94, 0xe5, 0x52, 0xcc, 0xaa, 0x5d, 0xe9, 0x5, 0xbb, + 0xfd, 0x17, 0xf5, 0xa1, 0xdb, 0x86, 0xc3, 0x3a, 0xf2, 0xd7, + 0x64, 0x71, 0xde, 0xf, 0xfd, 0x9f, 0x34, 0x6d, 0x26, 0x28, + 0xe6, 0xd6, 0x98, 0xea, 0xd7, 0x9d, 0x4c, 0x79, 0x2b, 0xa, + 0x9f, 0x4c, 0x75, 0x6f, 0xc7, 0xf2, 0xaf, 0x50, 0xb2, 0xd3, + 0xed, 0x74, 0xd8, 0x16, 0x1b, 0x4b, 0x68, 0xad, 0xa2, 0x51, + 0x80, 0x91, 0x20, 0x50, 0x3f, 0x1, 0x56, 0x28, 0xaf, 0xd5, + 0x30, 0xd8, 0x2c, 0x3e, 0x12, 0x3c, 0xb4, 0x60, 0x97, 0xe7, + 0xf7, 0x9f, 0x45, 0x4e, 0x94, 0x29, 0x2b, 0x41, 0x58, 0x2a, + 0x2b, 0x8b, 0x58, 0x6e, 0xe2, 0x68, 0xe7, 0x89, 0x26, 0x8d, + 0x86, 0xa, 0x48, 0xa1, 0x81, 0xfc, 0xd, 0x4b, 0x45, 0x76, + 0x34, 0x9e, 0x8c, 0xd8, 0xf2, 0xef, 0x1a, 0xfc, 0x5, 0xd1, + 0x75, 0xe8, 0x65, 0x9f, 0x49, 0x51, 0xa4, 0xea, 0x7, 0x2c, + 0x2, 0x67, 0xc9, 0x73, 0xe8, 0x57, 0xb7, 0xd4, 0x7e, 0x46, + 0xbe, 0x72, 0xd6, 0x74, 0x6b, 0xcf, 0xf, 0xea, 0x73, 0xd8, + 0x5f, 0xc0, 0xd6, 0xf7, 0x50, 0xb6, 0xd7, 0x46, 0xfe, 0x63, + 0xd4, 0x1f, 0x5a, 0xfb, 0x7a, 0xbc, 0x83, 0xf6, 0x87, 0xf0, + 0x7c, 0x5a, 0x87, 0x87, 0xd3, 0x5e, 0x89, 0x31, 0x77, 0x64, + 0x55, 0x25, 0x61, 0xfc, 0x51, 0x31, 0xc7, 0x3f, 0x42, 0x47, + 0xe6, 0x6b, 0xe2, 0xf3, 0xcc, 0x9a, 0x94, 0xa8, 0xcb, 0x13, + 0x87, 0x8f, 0x2c, 0xa3, 0xab, 0x4b, 0x66, 0xba, 0xfc, 0xcf, + 0x23, 0x19, 0x85, 0x8b, 0x8b, 0xa9, 0x5, 0x66, 0x8f, 0x9c, + 0xe8, 0xa2, 0x8a, 0xfc, 0xd0, 0xf0, 0x42, 0x8a, 0x28, 0xa0, + 0xf, 0xa8, 0x7e, 0x5, 0x78, 0xd2, 0x4f, 0x14, 0x78, 0x54, + 0xd9, 0xdd, 0x3e, 0xfb, 0xcd, 0x34, 0xac, 0x25, 0x89, 0xe5, + 0xe3, 0xc7, 0xc8, 0x4f, 0xbf, 0x4, 0x7e, 0x15, 0xe9, 0x55, + 0xf2, 0xd7, 0xc0, 0x5d, 0x71, 0xf4, 0x9f, 0x88, 0x16, 0xd6, + 0xfb, 0xb1, 0xd, 0xfa, 0x34, 0xe, 0x3b, 0x67, 0x1b, 0x94, + 0xfe, 0x63, 0x1f, 0x8d, 0x7d, 0x4b, 0x5f, 0xb0, 0x64, 0x58, + 0xb7, 0x8b, 0xc1, 0x45, 0xc9, 0xeb, 0x1d, 0x1f, 0xcb, 0x6f, + 0xc0, 0xfa, 0x7c, 0x1d, 0x47, 0x52, 0x92, 0xbe, 0xeb, 0x40, + 0xaf, 0x9c, 0x7e, 0x3f, 0xf8, 0xf1, 0xf5, 0x6d, 0x67, 0xfb, + 0x2, 0xd2, 0x42, 0x2c, 0xac, 0x88, 0x33, 0xed, 0x3c, 0x49, + 0x2f, 0xa7, 0xd1, 0x7f, 0x9e, 0x7d, 0x2b, 0xe8, 0x6d, 0x42, + 0xf1, 0x34, 0xfb, 0xb, 0x9b, 0xa9, 0xe, 0x12, 0x8, 0x9a, + 0x46, 0xfa, 00, 0x4f, 0xf4, 0xaf, 0x88, 0xef, 0xef, 0x24, + 0xd4, 0x6f, 0xae, 0x2e, 0xe6, 0x39, 0x96, 0x79, 0x1a, 0x57, + 0x3e, 0xec, 0x72, 0x7f, 0x9d, 0x79, 0x9c, 0x4d, 0x8b, 0x95, + 0x1a, 0x11, 0xa1, 0x7, 0xf1, 0xef, 0xe8, 0x8e, 0x7c, 0xc2, + 0xab, 0x8c, 0x14, 0x17, 0x52, 0xa, 0x28, 0xa2, 0xbf, 0x32, + 0x3c, 00, 0xa2, 0x8a, 0x96, 0xd2, 0xdd, 0xae, 0xee, 0xa1, + 0x81, 0x8, 0xf, 0x2b, 0xac, 0x60, 0x9e, 0x99, 0x27, 0x14, + 0xd2, 0x6d, 0xd9, 0x1, 0x7f, 0x40, 0xf0, 0xc6, 0xab, 0xe2, + 0x8b, 0xaf, 0xb3, 0xe9, 0x76, 0x33, 0x5e, 0x48, 0x3e, 0xf7, + 0x96, 0xbf, 0x2a, 0xff, 00, 0xbc, 0xdd, 0x7, 0xe3, 0x5e, + 0x8d, 0xa7, 0x7e, 0xcd, 0xfe, 0x20, 0xb9, 0x40, 0xd7, 0x57, + 0xb6, 0x56, 0x79, 0xfe, 0x1d, 0xcd, 0x23, 0xf, 0xc8, 0x63, + 0xf5, 0xaf, 0x7a, 0xf0, 0xb7, 0x86, 0xac, 0xfc, 0x27, 0xa1, + 0xda, 0xe9, 0xb6, 0x51, 0x85, 0x8e, 0x25, 0x1, 0x9b, 0x1c, + 0xc8, 0xdd, 0xd8, 0xfb, 0x93, 0x5a, 0xf5, 0xfa, 0x5e, 0x13, + 0x86, 0x70, 0xf0, 0x82, 0x78, 0x96, 0xe5, 0x2f, 0xb9, 0x7f, + 0x99, 0xef, 0xd2, 0xcb, 0xe0, 0x95, 0xea, 0x6a, 0xcf, 0x2, + 0x5f, 0xd9, 0x8e, 0xeb, 0x1f, 0x36, 0xbf, 0x8, 0x3e, 0xd6, + 0xc4, 0xff, 00, 0xec, 0xd4, 0xd7, 0xfd, 0x98, 0xef, 00, + 0xf9, 0x35, 0xe8, 0x9, 0xff, 00, 0x6a, 0xd9, 0x87, 0xfe, + 0xcd, 0x5e, 0xff, 00, 0x45, 0x7a, 0x5f, 0xea, 0xfe, 0x5d, + 0xff, 00, 0x3e, 0xff, 00, 0x17, 0xfe, 0x67, 0x47, 0xd4, + 0xa8, 0x76, 0xfc, 0x59, 0xf3, 0x8d, 0xd7, 0xec, 0xd7, 0xaf, + 0x44, 0x9, 0x83, 0x51, 0xb0, 0x9f, 0xd9, 0x8b, 0xa1, 0xff, + 00, 0xd0, 0x4d, 0x73, 0x3a, 0xb7, 0xc1, 0x7f, 0x17, 0x69, + 0x21, 0x99, 0xb4, 0xa6, 0xba, 0x41, 0xfc, 0x56, 0x8e, 0x24, + 0xfd, 0x7, 0x3f, 0xa5, 0x7d, 0x69, 0x45, 0x73, 0x54, 0xe1, + 0xac, 0xc, 0xd7, 0xb9, 0x78, 0xfc, 0xff, 00, 0xcc, 0xce, + 0x59, 0x7d, 0x17, 0xb5, 0xd1, 0xf0, 0xe5, 0xee, 0x9d, 0x77, + 0xa6, 0xc9, 0xe5, 0xdd, 0xda, 0xcd, 0x6b, 0x27, 0xf7, 0x66, + 0x8c, 0xa1, 0xfc, 0x8d, 0x7a, 0x5f, 0xec, 0xed, 0xa3, 0xb, + 0xff, 00, 0x1b, 0xcb, 0x78, 0xe3, 0x2b, 0x63, 0x6e, 0xce, + 0xa7, 0xd1, 0x9b, 0xe5, 0x1f, 0xa1, 0x6a, 0xfa, 0x3e, 0xff, + 00, 0x4d, 0xb4, 0xd5, 0x6d, 0xda, 0xb, 0xcb, 0x68, 0xae, + 0xa1, 0x61, 0x83, 0x1c, 0xc8, 0x18, 0x1f, 0xc0, 0xd6, 0x4f, + 0x86, 0xfc, 0xd, 0xa3, 0x78, 0x46, 0xea, 0xf6, 0x7d, 0x26, + 0xd3, 0xec, 0x8d, 0x77, 0xb7, 0xcc, 0x55, 0x62, 0x57, 0xe5, + 0xce, 0x30, 0xf, 0x4e, 0xa7, 0xa5, 0x71, 0x61, 0xb8, 0x71, + 0xe1, 0x71, 0x74, 0xeb, 0x29, 0xa9, 0x45, 0x3b, 0xeb, 0xa3, + 0xf2, 0xfc, 0x4c, 0x69, 0xe0, 0x1d, 0x3a, 0x91, 0x95, 0xee, + 0x91, 0xbf, 0x45, 0x14, 0x57, 0xdc, 0x1e, 0xc0, 0x51, 0x45, + 0x14, 00, 0x57, 0x13, 0xf1, 0x6e, 0xe3, 0xc8, 0xf0, 0xa4, + 0xe3, 0xfb, 0xc0, 0xd7, 0x6d, 0x5e, 0x6b, 0xf1, 0xca, 0xe3, + 0xc9, 0xf0, 0xbb, 0xc, 0xe3, 0x2a, 0xd5, 0xc5, 0x8d, 0x97, + 0x2e, 0x1e, 0x6f, 0xc8, 0xe7, 0xc4, 0x3b, 0x52, 0x93, 0xf2, + 0x3e, 0x20, 0xf1, 0x4, 0xbe, 0x65, 0xfd, 0xd3, 0x7a, 0xb9, + 0xaf, 0x9e, 0xfe, 0x34, 0xc4, 0x75, 0x29, 0x6d, 0xec, 0x14, + 0xe0, 0xdd, 0x4f, 0x1c, 00, 0xff, 00, 0xbc, 0xc1, 0x7f, + 0xad, 0x7b, 0xe6, 0xae, 0xfb, 0xa5, 0x98, 0xfa, 0xb1, 0xaf, + 0x12, 0xf1, 0x1d, 0xa7, 0xf6, 0xd7, 0xc5, 0x2f, 0x6, 0xe9, + 0xa3, 0xfe, 0x5e, 0xb5, 0xdb, 0x18, 0x78, 0xf7, 0x9d, 0x5, + 0x7c, 0x1e, 0x4d, 0x1b, 0xd4, 0x47, 0xe2, 0xf4, 0xd7, 0xb4, + 0xcd, 0x28, 0xaf, 0xef, 0x1f, 0xb2, 0xba, 0x6c, 0x1f, 0x65, + 0xd3, 0xed, 0x61, 0xff, 00, 0x9e, 0x71, 0x2a, 0x7e, 0x40, + 0xa, 0x2a, 0xcd, 0x15, 0xfa, 0x49, 0xfb, 0x80, 0x51, 0x45, + 0x14, 00, 0x51, 0x45, 0x21, 0x21, 0x41, 0x24, 0xe0, 0xe, + 0x49, 0xa0, 0xf, 0x9d, 0x7f, 0x6b, 0xdf, 0x1a, 0x2d, 0xb6, + 0x93, 0xa6, 0x78, 0x5e, 0x16, 0x6, 0x5b, 0xa7, 0xfb, 0x5d, + 0xc0, 0xd, 0xc8, 0x45, 0x38, 0x50, 0x47, 0xbb, 0x64, 0xff, + 00, 0xc0, 0x6b, 0xc3, 0xbe, 0x10, 0xf8, 0x59, 0xbc, 0x59, + 0xe3, 0xad, 0x36, 0xcf, 0x69, 0x68, 0x84, 0x81, 0xdf, 0x3, + 0xb0, 0xe6, 0x9d, 0xf1, 0xa3, 0xc6, 0x63, 0xc7, 0x7f, 0x11, + 0xf5, 0x5d, 0x46, 0x27, 0xdf, 0x67, 0x1b, 0x7d, 0x9a, 0xd8, + 0x83, 0x91, 0xe5, 0xa7, 00, 0x8f, 0x62, 0x77, 0x37, 0xe3, + 0x5e, 0xd3, 0xfb, 0x25, 0xf8, 0x3f, 0xca, 0xb7, 0xbe, 0xd7, + 0x66, 0x8c, 0x65, 0x8f, 0x95, 0x13, 0x11, 0xf9, 0xd7, 0xe7, + 0x55, 0x3f, 0xe1, 0x4f, 0x33, 0x51, 0x5a, 0xc6, 0xff, 00, + 0x82, 0xff, 00, 0x3f, 0xd4, 0xfc, 0xe6, 0x2f, 0xfb, 0x53, + 0x35, 0x72, 0xde, 0x29, 0xfe, 0xb, 0xfc, 0xcf, 0xa3, 0x60, + 0x85, 0x6d, 0xe1, 0x8e, 0x24, 0x18, 0x44, 0x50, 0xa0, 0x7b, + 0xa, 0x92, 0x8a, 0x2b, 0xf4, 0x5d, 0x8f, 0xd1, 0x82, 0x8a, + 0x28, 0xa0, 0x2, 0xb3, 0x3c, 0x4d, 0xe2, 0x4d, 0x33, 0xc1, + 0xde, 0x1e, 0xd4, 0x75, 0xcd, 0x66, 0xf2, 0x2d, 0x3f, 0x4a, + 0xd3, 0xe0, 0x7b, 0x9b, 0xab, 0xa9, 0x9b, 0x6a, 0x45, 0x1a, + 0x8c, 0xb3, 0x13, 0xf4, 0x15, 0xa7, 0x5f, 0x1, 0xff, 00, + 0xc1, 0x62, 0x3e, 0x30, 0xc9, 0xe0, 0xdf, 0x81, 0x1a, 0x3f, + 0x82, 0x2c, 0xa7, 0x31, 0xde, 0x78, 0xae, 0xfb, 0xfd, 0x20, + 0x2b, 0x60, 0xfd, 0x92, 0xc, 0x3b, 0xf, 0xa1, 0x73, 0x10, + 0xfa, 0x3, 0x40, 0x1f, 0x9e, 0x9f, 0xb6, 0x97, 0xed, 0x9b, + 0xe2, 0x4f, 0xda, 0xaf, 0xc7, 0x93, 0xb7, 0x9f, 0x36, 0x9b, + 0xe0, 0x8b, 0x9, 0x5e, 0x3d, 0x2b, 0x47, 0x8e, 0x42, 0x11, + 0x90, 0x37, 0x13, 0xcc, 0x3a, 0x34, 0x8c, 00, 0x3c, 0xfd, + 0xde, 0x83, 0xb9, 0x3a, 0x7f, 0x7, 0xbf, 0xe0, 0x9b, 0x1f, + 0x1c, 0x7e, 0x32, 0x68, 0x56, 0xfa, 0xdd, 0x9e, 0x81, 0x6b, + 0xe1, 0xdd, 0x1e, 0xe6, 0x31, 0x35, 0xbd, 0xd7, 0x88, 0x2e, + 0x7e, 0xcc, 0x66, 0x43, 0xc8, 0x65, 0x8c, 0x6, 0x7c, 0x63, + 0x9c, 0x95, 00, 0xd6, 0x6f, 0xfc, 0x13, 0xbb, 0xe1, 0xbe, + 0x87, 0xf1, 0x4b, 0xf6, 0xb4, 0xf0, 0x66, 0x93, 0xe2, 0x25, + 0x82, 0x7d, 0x32, 0xdc, 0xcd, 0xa8, 0x1b, 0x4b, 0x90, 0xa, + 0x5d, 0x3c, 0x31, 0x97, 0x48, 0xf0, 0x7a, 0xfc, 0xc0, 0x36, + 0x3b, 0x85, 0x35, 0xfb, 0x39, 0xfb, 0x62, 0x7c, 0x66, 0xb7, + 0xf8, 0x5, 0xfb, 0x39, 0x78, 0xc3, 0xc5, 0x2, 0x45, 0x86, + 0xf9, 0x2c, 0xcd, 0x96, 0x9a, 0x83, 0x8d, 0xd7, 0x52, 0x8d, + 0x91, 00, 0x3d, 0x89, 0xdd, 0xf4, 0x53, 0x4c, 0x84, 0xaf, + 0xab, 0x3f, 0x9e, 0x6f, 0x16, 0x78, 0x7d, 0xbc, 0x27, 0xe2, + 0x7d, 0x5b, 0x45, 0x7b, 0xcb, 0x6d, 0x41, 0xf4, 0xeb, 0xa9, + 0x2d, 0x5a, 0xea, 0xcd, 0x8b, 0x43, 0x29, 0x46, 0x2a, 0x59, + 0x9, 00, 0x95, 0x24, 0x70, 0x70, 0x2b, 0xf7, 0xe7, 0xf6, + 0x3, 0xf8, 0x22, 0x3e, 0x5, 0x7e, 0xcc, 0x3e, 0x14, 0xd2, + 0x67, 0x8b, 0xcb, 0xd6, 0x35, 0x38, 0xbf, 0xb6, 0x35, 0x1c, + 0x8f, 0x9b, 0xce, 0x9c, 0x6, 0xda, 0x7f, 0xdd, 0x4d, 0x89, + 0xff, 00, 0x1, 0xaf, 0xc5, 0x9f, 0xd8, 0xf3, 0xe0, 0xb4, + 0xbf, 0xb4, 0xf, 0xed, 0x17, 0xe1, 0xf, 0xa, 0x3a, 0x79, + 0xb6, 0x12, 0x5d, 0xb, 0xdd, 0x49, 0x98, 0x64, 0xb, 0x58, + 0xbf, 0x79, 0x2e, 0x7f, 0xde, 00, 0x27, 0xd5, 0xc5, 0x7e, + 0xd9, 0xfe, 0xd9, 0x7f, 0xb4, 0x8e, 0x8d, 0xfb, 0x30, 0x7c, + 0xf, 0xd5, 0xf5, 0x56, 0xbb, 0x82, 0x1f, 0x11, 0x5d, 0x5b, + 0x3d, 0x9e, 0x83, 0xa7, 0xe4, 0x6f, 0x9a, 0xe0, 0xae, 0xd5, + 0x60, 0xbd, 0x76, 0x26, 0x43, 0x31, 0xec, 0x6, 0x3a, 0x91, + 0x43, 0x5, 0xdc, 0xfc, 0x4a, 0xfd, 0xb3, 0x75, 0xfb, 0x5f, + 0x13, 0x7e, 0xd5, 0x7f, 0x14, 0xf5, 0x1b, 0x26, 0x57, 0xb5, + 0x93, 0x5e, 0xb9, 0x44, 0x74, 0xe8, 0xdb, 0x1b, 0x61, 0x3f, + 0x89, 0x52, 0x6b, 0xf5, 0x7f, 0xfe, 0x9, 0x19, 0xa1, 0x49, + 0xa4, 0xfe, 0xc8, 0x36, 0x77, 0x72, 0x2e, 0xdf, 0xed, 0x3d, + 0x66, 0xf6, 0xe5, 0x33, 0xdd, 0x43, 0x2c, 0x59, 0xfc, 0xe3, + 0x6a, 0xfc, 0x50, 0xd1, 0xf4, 0x9d, 0x57, 0xc7, 0x5e, 0x2a, + 0xb3, 0xd3, 0x6c, 0xd2, 0x4d, 0x43, 0x5a, 0xd5, 0xef, 0x12, + 0x8, 0x97, 0xab, 0xcd, 0x3c, 0xaf, 0x81, 0xf8, 0x96, 0x6a, + 0xfe, 0x91, 0x3e, 0x2, 0xfc, 0x2c, 0xb5, 0xf8, 0x27, 0xf0, + 0x73, 0xc2, 0x3e, 0x8, 0xb4, 0xda, 0x53, 0x46, 0xd3, 0xe3, + 0xb7, 0x92, 0x45, 0x1c, 0x49, 0x2e, 0x37, 0x4a, 0xff, 00, + 0xf0, 0x27, 0x2c, 0x7f, 0x1a, 0x18, 0x2d, 0xee, 0x77, 0x53, + 0xcc, 0x96, 0xd0, 0xc9, 0x34, 0x8c, 0x12, 0x38, 0xd4, 0xb3, + 0x31, 0xe8, 00, 0x19, 0x26, 0xbe, 0x2c, 0xf1, 0x46, 0xb5, + 0x27, 0x88, 0xfc, 0x45, 0xa8, 0xea, 0x52, 0x12, 0x4d, 0xcc, + 0xed, 0x20, 0xcf, 0x65, 0xcf, 0xca, 0x3f, 0x1, 0x81, 0x5f, + 0x4a, 0xfc, 0x73, 0xf1, 0x11, 0xd0, 0x7c, 0x3, 0x75, 0x1c, + 0x6f, 0xb2, 0xe2, 0xf9, 0x85, 0xaa, 0x63, 0xae, 0xf, 0x2f, + 0xff, 00, 0x8e, 0x82, 0x3f, 0x1a, 0xf9, 0x5a, 0xbf, 0x38, + 0xe2, 0x8c, 0x4f, 0x35, 0x48, 0x61, 0x97, 0x4d, 0x5f, 0xcf, + 0x6f, 0xeb, 0xcc, 0xf1, 0x33, 0x1a, 0x97, 0x92, 0xa6, 0xba, + 0x5, 0x14, 0x51, 0x5f, 0xa, 0x79, 0x1, 0x45, 0x14, 0x50, + 0x1, 0x46, 0x28, 0xa2, 0x80, 0xa, 0x28, 0xa2, 0x80, 0xa, + 0x7c, 0x10, 0x49, 0x73, 0x32, 0xc5, 0xc, 0x6f, 0x2c, 0xae, + 0x70, 0xa8, 0x8a, 0x59, 0x89, 0xf6, 0x2, 0xb4, 0x3c, 0x3f, + 0xa9, 0xd9, 0xe9, 0x5a, 0x82, 0xcd, 0x7d, 0xa5, 0xc3, 0xab, + 0x5b, 0xff, 00, 0x14, 0x12, 0xc8, 0xc9, 0xf9, 0x15, 0x3d, + 0x7e, 0xb9, 0xaf, 0xa9, 0xbe, 0x1a, 0x5c, 0xf8, 0x5f, 0x58, + 0xd1, 0x56, 0xff, 00, 0xc3, 0xda, 0x7d, 0xbd, 0x90, 0xce, + 0xc9, 0x63, 0x58, 0x82, 0xc9, 0x1b, 0xe3, 0xee, 0xb1, 0xea, + 0x7e, 0xb9, 0xe6, 0xbd, 0xdc, 0xb3, 0x2c, 0x8e, 0x63, 0x2e, + 0x5f, 0x6a, 0xa2, 0xfb, 0x6b, 0x7f, 0xf2, 0xfc, 0x4e, 0xbc, + 0x3e, 0x1d, 0x57, 0x76, 0xe6, 0xb1, 0xe2, 0xbe, 0x9, 0xf8, + 0xd, 0xad, 0x78, 0x86, 0x54, 0x9b, 0x55, 0x56, 0xd1, 0xec, + 0x3a, 0x9f, 0x30, 0x7e, 0xf9, 0xc7, 0xa0, 0x5e, 0xdf, 0x53, + 0xf9, 0x1a, 0xfa, 0x1f, 0xc3, 0x5e, 0x18, 0xd3, 0xbc, 0x25, + 0xa5, 0xc7, 0x61, 0xa6, 0xc0, 0x20, 0x81, 0x79, 0x27, 0xab, + 0x39, 0xee, 0xcc, 0x7b, 0x9a, 0xd5, 0xa2, 0xbf, 0x4b, 0xc0, + 0x65, 0x58, 0x6c, 0xbd, 0x5e, 0x92, 0xbc, 0xbb, 0xbd, 0xff, + 00, 0xe0, 0x1f, 0x41, 0x47, 0xd, 0x4e, 0x87, 0xc3, 0xbf, + 0x70, 0xa2, 0x8a, 0x2b, 0xd8, 0x3a, 0x82, 0x8a, 0x28, 0xa0, + 0x2, 0xb1, 0x3c, 0x69, 0xac, 0xaf, 0x87, 0xbc, 0x27, 0xaa, + 0xea, 0x5, 0xb6, 0x98, 0x2d, 0xdc, 0xa7, 0xfb, 0xe4, 0x61, + 0x47, 0xe6, 0x45, 0x6d, 0xd7, 0x91, 0xfe, 0xd1, 0xfa, 0xd9, + 0xb2, 0xf0, 0xa5, 0x9e, 0x9c, 0x8d, 0x87, 0xbd, 0xb8, 0xcb, + 0xf, 0x54, 0x41, 0x93, 0xff, 00, 0x8f, 0x15, 0xaf, 0x3f, + 0x30, 0xaf, 0xf5, 0x5c, 0x2d, 0x4a, 0xdd, 0x97, 0xe3, 0xd3, + 0xf1, 0x30, 0xaf, 0x3f, 0x67, 0x4e, 0x52, 0x3e, 0x70, 0x24, + 0x93, 0x93, 0xc9, 0xa2, 0x8a, 0x2b, 0xf0, 0xf3, 0xe4, 0x42, + 0x8a, 0x29, 0x42, 0x96, 0x20, 0x1, 0x92, 0x78, 0x2, 0x80, + 0x3e, 0x93, 0xfd, 0x9c, 0xf4, 0x71, 0x65, 0xe0, 0xcb, 0x8b, + 0xe6, 0x5c, 0x49, 0x7b, 0x72, 0xc4, 0x1f, 0xf6, 0x13, 0xe5, + 0x1f, 0xae, 0xea, 0xf5, 0x7a, 0xc4, 0xf0, 0x5e, 0x88, 0x3c, + 0x39, 0xe1, 0x4d, 0x2f, 0x4e, 00, 0x6, 0x82, 0x5, 0xf, + 0x8e, 0xec, 0x79, 0x63, 0xf9, 0x93, 0x5b, 0x75, 0xfb, 0x8e, + 0x2, 0x87, 0xd5, 0xb0, 0xb4, 0xe9, 0x76, 0x4b, 0xef, 0xeb, + 0xf8, 0x9f, 0x5d, 0x42, 0x1e, 0xce, 0x9c, 0x62, 0x14, 0x51, + 0x45, 0x77, 0x9b, 0x85, 0x79, 0x1f, 0xed, 0x15, 0xe2, 0x86, + 0xd3, 0x3c, 0x35, 0x6d, 0xa4, 0x42, 0xfb, 0x65, 0xd4, 0x1f, + 0x32, 0x1, 0xd7, 0xca, 0x5c, 0x13, 0xf9, 0x9c, 0x7e, 0x46, + 0xbd, 0x72, 0xbe, 0x51, 0xf8, 0xdd, 0xae, 0xb6, 0xb7, 0xf1, + 0xb, 0x50, 0x4d, 0xdb, 0xa1, 0xb3, 0xc5, 0xac, 0x63, 0x3d, + 0x36, 0x8f, 0x9b, 0xff, 00, 0x1e, 0x2d, 0x5f, 0x37, 0x9f, + 0xe2, 0x9e, 0x1b, 0x5, 0x25, 0x1d, 0xe5, 0xa7, 0xf9, 0xfe, + 0x7, 0x6, 0x36, 0xa7, 0x25, 0x16, 0x97, 0x5d, 0xe, 0xa, + 0x8a, 0x28, 0xaf, 0xc8, 0xcf, 0x99, 0xa, 0x28, 0xa9, 0x2d, + 0xe0, 0x7b, 0xab, 0x88, 0xa1, 0x88, 0x6e, 0x92, 0x46, 0x8, + 0xab, 0xea, 0x49, 0xc0, 0x14, 0xd2, 0xbe, 0x88, 0xf, 0x79, + 0xfd, 0x9c, 0xfc, 0x18, 0xb1, 0x5a, 0x5c, 0x78, 0x92, 0xe1, + 0x33, 0x24, 0xa5, 0xa0, 0xb6, 0xc8, 0xe8, 0xa3, 0xef, 0x30, + 0xfa, 0x9e, 0x3f, 0x3, 0xeb, 0x5e, 0xdd, 0x59, 0xbe, 0x1b, + 0xd1, 0x62, 0xf0, 0xee, 0x83, 0x61, 0xa6, 0xc2, 00, 0x4b, + 0x68, 0x56, 0x3c, 0x8e, 0xe4, 0xe, 0x4f, 0xe2, 0x72, 0x7f, + 0x1a, 0xd2, 0xaf, 0xdb, 0xb2, 0xfc, 0x2a, 0xc1, 0x61, 0xa1, + 0x45, 0x6e, 0x96, 0xbe, 0xbd, 0x4f, 0xae, 0xa1, 0x4d, 0x52, + 0xa6, 0xa2, 0x14, 0x51, 0x45, 0x7a, 0x26, 0xe1, 0x45, 0x14, + 0x50, 0x1, 0x59, 0x1e, 0x2e, 0xd3, 0xd7, 0x56, 0xf0, 0xb6, + 0xad, 0x66, 0xe3, 0x2b, 0x35, 0xac, 0x8b, 0xf8, 0xed, 0x38, + 0xfd, 0x6b, 0x5e, 0xaa, 0x6a, 0xf2, 0x88, 0x34, 0x9b, 0xd9, + 0x1b, 0xee, 0xa4, 0xe, 0xc7, 0xf0, 0x53, 0x59, 0xd5, 0x4a, + 0x50, 0x92, 0x7b, 0x59, 0x93, 0x25, 0x78, 0xb4, 0xcf, 0x87, + 0xe8, 0xa2, 0x8a, 0xfc, 0xc, 0xf8, 0xc0, 0xa2, 0x8a, 0x28, + 0x3, 0x7b, 0xc0, 0x57, 0x26, 0xd3, 0xc6, 0xda, 0x14, 0xa0, + 0xe3, 0x17, 0xb0, 0x8f, 0xc0, 0xb8, 0x7, 0xf9, 0xd7, 0xd9, + 0xb5, 0xf1, 0x67, 0x83, 0x62, 0x33, 0x78, 0xbb, 0x44, 0x45, + 0xea, 0xd7, 0xb0, 0x8f, 0xfc, 0x7c, 0x57, 0xda, 0x75, 0xfa, + 0x47, 0xa, 0xb7, 0xec, 0x6a, 0xae, 0x97, 0x5f, 0x91, 0xee, + 0xe5, 0xbf, 0xc, 0x8c, 0x3f, 0x1c, 0x86, 0x6f, 0x5, 0xeb, + 0xa1, 0x33, 0xbb, 0xec, 0x33, 0x63, 0x1f, 0xee, 0x1a, 0xf8, + 0xc2, 0xbe, 0xe6, 0xb9, 0xb7, 0x4b, 0xbb, 0x69, 0x60, 0x90, + 0x6e, 0x8e, 0x54, 0x28, 0xc0, 0xf7, 0x4, 0x60, 0xd7, 0xc5, + 0x9e, 0x25, 0xd0, 0xa7, 0xf0, 0xd6, 0xbd, 0x7d, 0xa6, 0x5c, + 0x29, 0x59, 0x2d, 0xe5, 0x28, 0x9, 0x1f, 0x79, 0x7f, 0x85, + 0xbf, 0x11, 0x83, 0xf8, 0xd7, 0x37, 0x15, 0x52, 0x95, 0xe9, + 0x55, 0xe9, 0xaa, 0x23, 0x32, 0x8b, 0xbc, 0x64, 0x66, 0x51, + 0x45, 0x15, 0xf0, 0x7, 0x8a, 0x14, 0xaa, 0xc5, 0x18, 0x32, + 0x92, 0x18, 0x1c, 0x82, 0x3b, 0x52, 0x51, 0x40, 0x1f, 0x49, + 0xfc, 0x39, 0xf8, 0xe5, 0xa6, 0x6b, 0x16, 0x30, 0x59, 0x6b, + 0x93, 0xae, 0x9f, 0xa9, 0x46, 0xa1, 0xc, 0xf2, 0x9c, 0x45, + 0x37, 0x6c, 0xe7, 0xf8, 0x4f, 0xa8, 0x3f, 0x85, 0x7a, 0xac, + 0x53, 0x47, 0x3c, 0x6b, 0x24, 0x4e, 0xb2, 0x46, 0xc3, 0x21, + 0x90, 0xe4, 0x11, 0xf5, 0xaf, 0x85, 0xeb, 0x63, 0x43, 0xf1, + 0x86, 0xb7, 0xe1, 0xa3, 0xff, 00, 0x12, 0xcd, 0x4e, 0xe6, + 0xd1, 0x7f, 0xe7, 0x9a, 0x3e, 0x50, 0xff, 00, 0xc0, 0x4f, + 0x1f, 0xa5, 0x7d, 0xbe, 0xb, 0x89, 0xaa, 0x52, 0x8a, 0x86, + 0x26, 0x3c, 0xd6, 0xea, 0xb7, 0xff, 00, 0x83, 0xf8, 0x1e, + 0xbd, 0x2c, 0xc2, 0x51, 0x56, 0xa8, 0xae, 0x7d, 0xa7, 0x45, + 0x7c, 0xdf, 0xa0, 0xfe, 0xd1, 0xda, 0xed, 0x8e, 0xd4, 0xd4, + 0xed, 0x2d, 0xf5, 0x38, 0xc7, 0x56, 0x5f, 0xdd, 0x49, 0xf9, + 0x8c, 0x8f, 0xd2, 0xbb, 0xed, 0x13, 0xf6, 0x87, 0xf0, 0xd6, + 0xa4, 0xc1, 0x2f, 0x52, 0xe7, 0x4b, 0x73, 0xfc, 0x52, 0xa6, + 0xf4, 0xfc, 0xd7, 0x27, 0xf3, 0x15, 0xf5, 0x74, 0x33, 0xcc, + 0x5, 0x7f, 0xf9, 0x79, 0xca, 0xfc, 0xf4, 0xff, 00, 0x81, + 0xf8, 0x9e, 0x8c, 0x31, 0x94, 0x67, 0xd6, 0xde, 0xa7, 0xa9, + 0x51, 0x59, 0xba, 0x3f, 0x89, 0x34, 0xaf, 0x10, 0x45, 0xe6, + 0x69, 0xba, 0x85, 0xbd, 0xea, 0xf7, 0xf2, 0x64, 0xc, 0x47, + 0xd4, 0x75, 0x15, 0xa5, 0x5e, 0xe4, 0x65, 0x19, 0xae, 0x68, + 0xbb, 0xa3, 0xb1, 0x34, 0xd5, 0xd0, 0x51, 0x45, 0x15, 0x43, + 0xa, 0x28, 0xa2, 0x80, 0xa, 0x28, 0xa2, 0x80, 0xa, 0xf2, + 0xf, 0xda, 0x1e, 0xeb, 0xca, 0xd0, 0x36, 0xe7, 0xfe, 0x59, + 0x9a, 0xf5, 0xfa, 0xf0, 0x6f, 0xda, 0x5e, 0xf8, 0x47, 0x61, + 0xe5, 0x67, 0x91, 0x1d, 0x79, 0x19, 0xb4, 0xb9, 0x30, 0x75, + 0x1f, 0x91, 0xc1, 0x8e, 0x97, 0x2e, 0x1e, 0x4c, 0xf9, 0x7, + 0x53, 0x6f, 0x95, 0xcf, 0xb9, 0xaf, 0x34, 0xf0, 0x2d, 0x92, + 0xeb, 0x9f, 0xb5, 0x7, 0xc3, 0x3b, 0x26, 0x1b, 0x81, 0xd7, + 0xad, 0xe4, 0xc7, 0xfb, 0x84, 0xbf, 0xfe, 0xcb, 0x5e, 0x8d, + 0xaa, 0x36, 0x22, 0x63, 0xec, 0x6b, 0x94, 0xfd, 0x9b, 0xec, + 0xff, 00, 0xb6, 0x3f, 0x6c, 0xbf, 0x87, 0xf1, 0xe3, 0x70, + 0x86, 0x7b, 0x9b, 0x93, 0xed, 0xb2, 0xda, 0x53, 0x9f, 0xcf, + 0x15, 0xf2, 0xd9, 0x24, 0x7d, 0xf3, 0xf2, 0x3c, 0xb1, 0x7b, + 0x4c, 0xe2, 0x97, 0x95, 0xd9, 0xfa, 0xcf, 0x45, 0x14, 0x57, + 0xe8, 0x7, 0xed, 0x61, 0x45, 0x14, 0x50, 0x1, 0x5c, 0x3f, + 0xc6, 0x8f, 0x18, 0xf, 0x4, 0x7c, 0x37, 0xd6, 0x35, 0x5, + 0x62, 0xb7, 0xf, 0x17, 0xd9, 0xad, 0xf6, 0xf5, 0xf3, 0x1f, + 0xe5, 0x53, 0xf8, 0x64, 0x9f, 0xc2, 0xbb, 0x8a, 0xf9, 0x5f, + 0xf6, 0xbf, 0xf1, 0x87, 0xda, 0xb5, 0x6d, 0x2b, 0xc3, 0x31, + 0x1f, 0x92, 0xd9, 0x3e, 0xd9, 0x39, 0xe7, 0xef, 0x36, 0x42, + 0x8f, 0xcb, 0x27, 0xf1, 0xaf, 0x37, 0x31, 0xc4, 0x7d, 0x5b, + 0xd, 0x39, 0xf5, 0xd9, 0x7a, 0xb3, 0xca, 0xcd, 0x31, 0x3f, + 0x54, 0xc2, 0x4e, 0xa2, 0xdf, 0x65, 0xea, 0xff, 00, 0xab, + 0x9f, 0x3e, 0x58, 0x5a, 0xbd, 0xe5, 0xd4, 0x30, 0x46, 0x37, + 0x3b, 0xb0, 0x50, 0x7, 0xa9, 0xaf, 0xd0, 0x3f, 0x86, 0x9e, + 0x19, 0x8f, 0xc2, 0x7e, 0xc, 0xd3, 0x6c, 0x11, 0x2, 0xb8, + 0x88, 0x34, 0x9e, 0xec, 0x47, 0x35, 0xf2, 0x27, 0xec, 0xf7, + 0xe1, 0x13, 0xe2, 0x9f, 0x1f, 0x5a, 0x97, 0x5c, 0xdb, 0xdb, + 0x7e, 0xf5, 0xcf, 0xd3, 0xa5, 0x7d, 0xc4, 0xa0, 0x28, 00, + 0x70, 0x7, 0x15, 0xf3, 0xdc, 0x3d, 0x87, 0xd2, 0x78, 0x87, + 0xe8, 0xbf, 0x53, 0xc2, 0xe1, 0xcc, 0x37, 0x25, 0x39, 0x57, + 0x7d, 0x74, 0x42, 0xd1, 0x45, 0x15, 0xf6, 0x67, 0xd9, 0x5, + 0x14, 0x51, 0x40, 0x5, 0x7e, 0x55, 0x7f, 0xc1, 0x6d, 0x3c, + 0x2b, 0xa8, 0x36, 0xa3, 0xf0, 0xc7, 0xc4, 0x81, 0x19, 0xb4, + 0xa5, 0x8a, 0xef, 0x4f, 0x67, 0x1d, 0x12, 0x62, 0x52, 0x40, + 0xf, 0xd5, 0x43, 0x7f, 0xdf, 0x26, 0xbf, 0x52, 0xb5, 0x4d, + 0x5e, 0xc7, 0x43, 0xb3, 0x6b, 0xbd, 0x46, 0xf6, 0xde, 0xc2, + 0xd5, 0x48, 0x56, 0x9e, 0xea, 0x55, 0x8d, 0x1, 0x27, 00, + 0x16, 0x62, 0x7, 0x24, 0x81, 0x5e, 0x73, 0xf1, 0xc7, 0xe1, + 0xf, 0x82, 0xff, 00, 0x69, 0xef, 0x86, 0x1a, 0x8f, 0x83, + 0x35, 0xeb, 0x98, 0xee, 0xf4, 0xeb, 0xbd, 0xb2, 0xc5, 0x73, + 0x63, 0x3a, 0x99, 0x6d, 0xa6, 0x5e, 0x52, 0x54, 0x23, 0x3c, + 0x83, 0xdb, 0xa1, 0x4, 0x83, 0xc1, 0xa0, 0x4f, 0x53, 0xf9, + 0xcd, 0xf0, 0xaf, 0x8a, 0xb5, 0x8f, 0x3, 0xf8, 0x8b, 0x4f, + 0xd7, 0xb4, 0xd, 0x46, 0xe3, 0x49, 0xd6, 0x74, 0xf9, 0x44, + 0xf6, 0xb7, 0xb6, 0xaf, 0xb6, 0x48, 0x9c, 0x74, 0x20, 0xfe, + 0x9e, 0xe0, 0x90, 0x6b, 0xd8, 0x7e, 0x39, 0x7e, 0xda, 0xdf, + 0x14, 0xbf, 0x68, 0xbf, 0x1, 0x68, 0xfe, 0x13, 0xf1, 0xce, + 0xa9, 0x69, 0xa9, 0x58, 0x69, 0x97, 0x42, 0xf1, 0x27, 0x86, + 0xd1, 0x60, 0x9a, 0x69, 0x2, 0x32, 0x3, 0x29, 0x5c, 0x2b, + 0x60, 0x33, 0x74, 0x51, 0xc9, 0xaf, 0x44, 0xf8, 0xd9, 0xff, + 00, 0x4, 0xbf, 0xf8, 0xd9, 0xf0, 0xa2, 0xfa, 0xea, 0x5d, + 0x27, 0x44, 0x1e, 0x39, 0xd0, 0x91, 0xd8, 0xc5, 0x7d, 0xa1, + 0xb6, 0xf9, 0x76, 0x67, 0x82, 0xf0, 0x1c, 0x38, 0x6c, 0x76, + 0x50, 0xc3, 0xde, 0xbe, 0x79, 0xb8, 0xf8, 0x25, 0xf1, 0x12, + 0xd2, 0xe4, 0xdb, 0xcd, 0xe0, 0x3f, 0x12, 0xc5, 0x38, 0x38, + 0xf2, 0xdb, 0x48, 0xb8, 0xd, 0x9f, 0xa6, 0xca, 0xa2, 0x35, + 0x3a, 0x5f, 0xd9, 0xdb, 0xf6, 0x95, 0xf1, 0x47, 0xec, 0xc5, + 0xe2, 0xd, 0x5f, 0x5f, 0xf0, 0x7d, 0xa6, 0x96, 0xfa, 0xe5, + 0xfd, 0x9f, 0xd8, 0x56, 0xf7, 0x51, 0xb7, 0x33, 0x1b, 0x68, + 0xcb, 0x6, 0x6f, 0x2c, 0x6e, 0x3, 0x2c, 0x55, 0x73, 0x9c, + 0xfd, 0xd1, 0x5c, 0xdf, 0xc5, 0x9f, 0x8d, 0x1e, 0x35, 0xf8, + 0xe5, 0xe2, 0x63, 0xaf, 0xf8, 0xe3, 0xc4, 0x37, 0x7e, 0x20, + 0xd4, 0x82, 0x94, 0x8d, 0xee, 0x8, 0x9, 0xa, 0x67, 0x3b, + 0x23, 0x45, 0x1, 0x51, 0x7d, 0x94, 0xa, 0xf4, 0xdf, 0x86, + 0x7f, 0xb0, 0x3f, 0xc7, 0x6f, 0x8a, 0x97, 0x31, 0x2e, 0x99, + 0xe0, 0xd, 0x47, 0x4c, 0xb5, 0x7e, 0xb7, 0xba, 0xda, 0xfd, + 0x86, 0x15, 0x1e, 0xa7, 0xcc, 0xc3, 0x1f, 0xc1, 0x4d, 0x7e, + 0x8b, 0xfe, 0xc9, 0xff, 00, 0xf0, 0x4a, 0xf, 0xb, 0xfc, + 0x27, 0xbd, 0xb2, 0xf1, 0x37, 0xc4, 0xbb, 0xb8, 0x3c, 0x65, + 0xe2, 0x6b, 0x79, 0x16, 0x6b, 0x7d, 0x3e, 0x10, 0x46, 0x9d, + 0x6a, 0xe3, 0x90, 0x48, 0x60, 0xc, 0xcc, 0xf, 0x76, 0x1, + 0x78, 0x1f, 0x2f, 0x7a, 0x2, 0xcc, 0xf3, 0xaf, 0xf8, 0x25, + 0x8f, 0xec, 0x3b, 0x79, 0xa4, 0xdd, 0xda, 0xfc, 0x65, 0xf1, + 0xde, 0x9b, 0xf6, 0x79, 0xc, 0x64, 0xf8, 0x73, 0x4d, 0xba, + 0x8c, 0x89, 0x13, 0x3c, 0x1b, 0xb7, 0x53, 0xd3, 0x23, 0x21, + 0x7, 0x5e, 0x4b, 0x7a, 0x57, 0xea, 0x25, 0x22, 0xa8, 0x45, + 0xa, 0xa0, 0x2a, 0x81, 0x80, 00, 0xc0, 0x2, 0xa2, 0xbc, + 0xbb, 0x8e, 0xc6, 0xd2, 0x6b, 0x99, 0x9b, 0x64, 0x30, 0xa1, + 0x91, 0xd8, 0xf6, 00, 0x64, 0xd4, 0xb7, 0x6d, 0x59, 0x7b, + 0x23, 0xe7, 0x5f, 0xda, 0x33, 0xc4, 0x23, 0x50, 0xf1, 0x4d, + 0xae, 0x97, 0x1b, 0xe6, 0x3b, 0x8, 0xb2, 0xe0, 0x1e, 0x3c, + 0xc7, 0xe4, 0xff, 00, 0xe3, 0xa1, 0x7f, 0x3a, 0xf2, 0x4a, + 0xbf, 0xaf, 0x6a, 0xb2, 0x6b, 0xba, 0xd5, 0xf6, 0xa1, 0x29, + 0x26, 0x4b, 0x99, 0x9e, 0x53, 0x9e, 0xd9, 0x39, 0x3, 0xf0, + 0x1c, 0x55, 0xa, 0xfc, 0x3b, 0x1f, 0x89, 0x78, 0xbc, 0x4c, + 0xeb, 0x77, 0x7f, 0x87, 0x4f, 0xc0, 0xf9, 0x1a, 0xd5, 0x3d, + 0xad, 0x47, 0x3e, 0xe1, 0x45, 0x14, 0x57, 0x1, 0x89, 0xdd, + 0x7c, 0x28, 0xf8, 0x72, 0x9f, 0x10, 0xf5, 0x4b, 0xc8, 0xae, + 0x66, 0x96, 0xda, 0xce, 0xda, 0x20, 0xcd, 0x24, 0x20, 0x67, + 0x79, 0x3f, 0x28, 0xe4, 0x63, 0xb3, 0x7e, 0x55, 0xe8, 0xf3, + 0x7e, 0xcc, 0x96, 0x4, 0x1f, 0x27, 0x5c, 0xb9, 0x43, 0xdb, + 0x7c, 0x2a, 0xdf, 0xc8, 0x8a, 0xde, 0xf8, 0x1, 0xe1, 0xd6, + 0xd1, 0xbc, 0xe, 0x2e, 0xe5, 0x5d, 0xb3, 0x6a, 0x32, 0x99, + 0xf9, 0xeb, 0xb0, 0x70, 0xbf, 0xc8, 0x9f, 0xc6, 0xbd, 0x32, + 0xbf, 0x50, 0xcb, 0x32, 0x5c, 0x2c, 0xf0, 0x70, 0x96, 0x22, + 0x9d, 0xe4, 0xf5, 0xeb, 0xd7, 0x6f, 0xc0, 0xfa, 0x1c, 0x3e, + 0x12, 0x9b, 0xa4, 0x9c, 0xd6, 0xac, 0xf9, 0xa7, 0xc5, 0x1f, + 0xb3, 0xd6, 0xb7, 0xa2, 0x59, 0xc9, 0x75, 0xa7, 0xdc, 0xc7, + 0xab, 0xa4, 0x63, 0x2d, 0x14, 0x68, 0x52, 0x5c, 0x7b, 0x2e, + 0x48, 0x3f, 0x9e, 0x6b, 0xca, 0xd9, 0x4a, 0xb1, 0x56, 0x4, + 0x10, 0x70, 0x41, 0xea, 0x2b, 0xee, 0xaa, 0xf9, 0x77, 0xe3, + 0xd7, 0x85, 0xe2, 0xf0, 0xff, 00, 0x8d, 0x3e, 0xd3, 0x6c, + 0x81, 0x20, 0xd4, 0x63, 0xfb, 0x41, 0x51, 0xd0, 0x49, 0x92, + 0x1f, 0x1f, 0xa1, 0xfc, 0x6b, 0xc5, 0xcf, 0x32, 0x5a, 0x58, + 0x3a, 0x4b, 0x11, 0x87, 0xd1, 0x6c, 0xd6, 0xff, 00, 0x33, + 0x93, 0x17, 0x84, 0x8d, 0x28, 0xf3, 0xc3, 0x63, 0xcd, 0xa8, + 0xa2, 0x8a, 0xf8, 0x93, 0xc9, 0xa, 0xf5, 0xdf, 0xd9, 0xbf, + 0x5b, 0x7b, 0x5f, 0x14, 0xde, 0xe9, 0x85, 0xbf, 0x73, 0x77, + 0x6f, 0xe6, 0x5, 0xff, 00, 0x6d, 0xf, 0x1f, 0xa1, 0x6a, + 0xf2, 0x2a, 0xed, 0xbe, 0xc, 0x5d, 0x7d, 0x93, 0xe2, 0x5e, + 0x8a, 0x73, 0x80, 0xee, 0xf1, 0x9f, 0xc5, 0x18, 0xf, 0xd7, + 0x15, 0xea, 0x65, 0x75, 0x5d, 0x1c, 0x6d, 0x29, 0x2e, 0xe9, + 0x7d, 0xfa, 0x1d, 0x18, 0x79, 0x72, 0xd6, 0x8b, 0xf3, 0x3e, + 0xb5, 0xa2, 0x8a, 0x2b, 0xf6, 0xc3, 0xeb, 0x42, 0x8a, 0x28, + 0xa0, 0x2, 0x8a, 0x28, 0xa0, 0x2, 0xbe, 0x61, 0xfd, 0xa0, + 0xb5, 0xef, 0xed, 0x5f, 0x1d, 0x1b, 0x35, 0x6c, 0xc5, 0xa7, + 0xc2, 0xb1, 0x63, 0xfd, 0xb6, 0xf9, 0x9b, 0xf9, 0xa8, 0xfc, + 0x2b, 0xe9, 0xa9, 0xe7, 0x4b, 0x68, 0x24, 0x9a, 0x43, 0xb6, + 0x38, 0xd4, 0xbb, 0x13, 0xd8, 0x1, 0x93, 0x5f, 0x14, 0xf8, + 0x8f, 0x57, 0x6d, 0x7b, 0x5e, 0xd4, 0x35, 0x17, 0xce, 0x6e, + 0xa7, 0x79, 0x70, 0x7b, 0x2, 0x78, 0x1f, 0x96, 0x2b, 0xe3, + 0x38, 0x9f, 0x11, 0xc9, 0x86, 0x85, 0x15, 0xf6, 0x9f, 0xe0, + 0xbf, 0xe0, 0xd8, 0xf2, 0x73, 0x19, 0xda, 0xa, 0x1d, 0xcc, + 0xea, 0x28, 0xa2, 0xbf, 0x32, 0x3c, 00, 0xae, 0x8f, 0xe1, + 0xd6, 0x8c, 0x75, 0xff, 00, 0x1b, 0xe8, 0xd6, 0x7b, 0x77, + 0x23, 0x5c, 0x2b, 0xb8, 0xc7, 0xf0, 0x2f, 0xcc, 0xdf, 0xa0, + 0x35, 0xce, 0x57, 0xb0, 0x7e, 0xcd, 0x9a, 0x3f, 0xda, 0x7c, + 0x49, 0xa9, 0x6a, 0x2c, 0x32, 0xb6, 0xb6, 0xe2, 0x35, 0x3f, + 0xed, 0x39, 0xff, 00, 0x5, 0x3f, 0x9d, 0x7a, 0x59, 0x6d, + 0xf, 0xac, 0xe3, 0x29, 0xd2, 0xee, 0xff, 00, 0x5, 0xab, + 0x37, 0xa1, 0xf, 0x69, 0x56, 0x31, 0x3e, 0x8b, 0xa2, 0x8a, + 0x2b, 0xf6, 0xe3, 0xeb, 0x82, 0x8a, 0x28, 0xa0, 0x8, 0xee, + 0x26, 0x5b, 0x6b, 0x79, 0x65, 0x73, 0x84, 0x8d, 0x4b, 0x13, + 0xec, 0x6, 0x6b, 0xe2, 0x2d, 0x52, 0xf9, 0xf5, 0x3d, 0x4e, + 0xee, 0xf2, 0x43, 0x97, 0xb8, 0x95, 0xe5, 0x6f, 0xab, 0x12, + 0x7f, 0xad, 0x7d, 0x89, 0xe3, 0xa9, 0xda, 0xd7, 0xc1, 0x5a, + 0xf4, 0xa8, 0x70, 0xc9, 0x63, 0x31, 0x7, 0xdf, 0x61, 0xaf, + 0x8c, 0x6b, 0xf3, 0xce, 0x2a, 0xa8, 0xf9, 0xa9, 0x53, 0xf5, + 0x7f, 0x91, 0xe1, 0xe6, 0x52, 0xd6, 0x31, 0xa, 0x28, 0xa2, + 0xbe, 0x8, 0xf1, 0x82, 0xba, 0xbf, 0x85, 0x9a, 0x60, 0xd5, + 0xbe, 0x20, 0xe8, 0x70, 0x30, 0xca, 0x2d, 0xc0, 0x95, 0xbe, + 0x88, 0xb, 0x7f, 0xec, 0xb5, 0xca, 0x57, 0xa2, 0x7c, 0x4, + 0x50, 0x7e, 0x24, 0xd9, 0x13, 0xd4, 0x45, 0x29, 0x1f, 0xf7, + 0xc1, 0xaf, 0x43, 0x2f, 0x82, 0xa9, 0x8b, 0xa5, 0x17, 0xd6, + 0x4b, 0xf3, 0x36, 0xa2, 0xb9, 0xaa, 0xc5, 0x79, 0xa3, 0xea, + 0x7a, 0x28, 0xa2, 0xbf, 0x70, 0x3e, 0xbc, 0x28, 0xa2, 0x8a, + 00, 0x28, 0xa2, 0x8a, 00, 0x2b, 0x95, 0xf8, 0xa3, 0xaa, + 0xd, 0x1f, 0xe1, 0xfe, 0xb9, 0x71, 0x9c, 0x31, 0xb7, 0x68, + 0x97, 0xfd, 0xe7, 0xf9, 0x47, 0xf3, 0xae, 0xaa, 0xbc, 0x67, + 0xf6, 0x92, 0xf1, 0x1a, 0xdb, 0x68, 0xb6, 0x1a, 0x2a, 0x37, + 0xef, 0x6e, 0xa4, 0xf3, 0xe4, 0x1e, 0x88, 0xbd, 0x3f, 0x36, + 0x3f, 0xf8, 0xed, 0x79, 0x99, 0x9d, 0x75, 0x86, 0xc1, 0xd4, + 0xa8, 0xfb, 0x69, 0xea, 0xf4, 0x47, 0x3e, 0x22, 0x7e, 0xce, + 0x94, 0xa4, 0x7c, 0xf5, 0x45, 0x14, 0x57, 0xe2, 0x47, 0xc9, + 0x5, 0x14, 0x51, 0x40, 0x1d, 0x6f, 0xc2, 0x7b, 0x3f, 0xb7, + 0x7c, 0x45, 0xd0, 0xa3, 0xc6, 0x42, 0xdc, 0x9, 0xf, 0xfc, + 0x4, 0x16, 0xfe, 0x95, 0xf5, 0xf5, 0x7c, 0xe3, 0xfb, 0x37, + 0xe8, 0x7f, 0x6c, 0xf1, 0x45, 0xee, 0xa6, 0xcb, 0x94, 0xb2, + 0x83, 0x62, 0x9f, 0xf6, 0xdc, 0xe3, 0xf9, 0x6, 0xfc, 0xeb, + 0xe8, 0xea, 0xfd, 0x4f, 0x86, 0x68, 0xba, 0x78, 0x27, 0x37, + 0xf6, 0x9b, 0x7f, 0x76, 0x87, 0xd1, 0x65, 0xf1, 0xb5, 0x2b, + 0xf7, 0x61, 0x5e, 0x6b, 0xf1, 0x7f, 0xe1, 0x58, 0xf1, 0xbd, + 0xa2, 0xdf, 0xd8, 0x5, 0x8f, 0x58, 0xb7, 0x42, 00, 0x3c, + 0x9, 0xd7, 0xfb, 0xa4, 0xfa, 0xfa, 0x1f, 0xc3, 0xe9, 0xe9, + 0x54, 0x57, 0xd1, 0xe2, 0x70, 0xd4, 0xf1, 0x74, 0x9d, 0x1a, + 0xaa, 0xe9, 0x9d, 0xf5, 0x29, 0xc6, 0xac, 0x5c, 0x65, 0xb1, + 0xf0, 0xdd, 0xed, 0x8d, 0xc6, 0x9b, 0x75, 0x25, 0xb5, 0xd4, + 0x32, 0x5b, 0xdc, 0x46, 0x76, 0xbc, 0x52, 0x2e, 0xd6, 0x53, + 0xee, 0x2a, 0xa, 0xfb, 0x17, 0xc6, 0x3f, 0xf, 0x34, 0x4f, + 0x1c, 0x42, 0xa3, 0x52, 0xb6, 0xfd, 0xfa, 0xc, 0x25, 0xcc, + 0x47, 0x6c, 0x8b, 0xf8, 0xf7, 0x1e, 0xc7, 0x22, 0xbc, 0x3f, + 0xc5, 0x3f, 0xb3, 0xde, 0xbb, 0xa4, 0x34, 0x92, 0xe9, 0x4f, + 0x1e, 0xaf, 0x6a, 0x39, 0xa, 0xe, 0xc9, 0x80, 0xff, 00, + 0x74, 0xf0, 0x7f, 0x3, 0xf8, 0x57, 0xe6, 0x38, 0xee, 0x1f, + 0xc5, 0x61, 0x5b, 0x95, 0x25, 0xcf, 0x1f, 0x2d, 0xfe, 0x6b, + 0xfc, 0x8f, 0x9e, 0xad, 0x82, 0xa9, 0x4f, 0x58, 0xea, 0x8f, + 0x2a, 0xa2, 0xac, 0x5f, 0x69, 0xf7, 0x5a, 0x65, 0xc3, 0x41, + 0x79, 0x6f, 0x2d, 0xac, 0xcb, 0xd6, 0x39, 0x90, 0xab, 0xf, + 0xc0, 0xd5, 0x7a, 0xf9, 0x86, 0x9c, 0x5d, 0x99, 0xe7, 0xec, + 0x14, 0x51, 0x45, 0x20, 0xa, 0x28, 0xa2, 0x80, 0x25, 0xb5, + 0xbb, 0x9e, 0xc6, 0x75, 0x9a, 0xda, 0x69, 0x2d, 0xe6, 0x5e, + 0x56, 0x48, 0x9c, 0xab, 0xf, 0xa1, 0x15, 0xe9, 0x5e, 0x11, + 0xf8, 0xfb, 0xaf, 0x68, 0x6e, 0x91, 0x6a, 0x64, 0x6b, 0x36, + 0x9d, 0xf, 0x98, 0x42, 0xca, 0xbf, 0x46, 0xc7, 0x3f, 0x8e, + 0x7e, 0xb5, 0xe6, 0x14, 0x57, 0x66, 0x1b, 0x19, 0x5f, 0x9, + 0x2e, 0x6a, 0x13, 0x6b, 0xf2, 0xfb, 0xb6, 0x35, 0xa7, 0x56, + 0x74, 0x9d, 0xe0, 0xec, 0x7d, 0x8f, 0xe0, 0xdf, 0x1f, 0xe8, + 0xfe, 0x38, 0xb4, 0xf3, 0x74, 0xeb, 0x8f, 0xdf, 0x28, 0xfd, + 0xe5, 0xb4, 0xbf, 0x2c, 0xa9, 0xf5, 0x1d, 0xc7, 0xb8, 0xe2, + 0xba, 0x4a, 0xf8, 0x7b, 0x4b, 0xd5, 0x2e, 0xf4, 0x5d, 0x42, + 0xb, 0xdb, 0x19, 0xda, 0xde, 0xea, 0x16, 0xdc, 0x92, 0x27, + 0x50, 0x7f, 0xcf, 0x6a, 0xfa, 0xa3, 0xe1, 0x4f, 0xc4, 0x88, + 0xbc, 0x7d, 0xa3, 0x91, 0x36, 0x23, 0xd5, 0x6d, 0x80, 0x17, + 0x31, 0x81, 0x85, 0x6c, 0xf4, 0x75, 0xf6, 0x38, 0xfc, 0xf, + 0xe1, 0x5f, 0xa4, 0xe5, 0x19, 0xdc, 0x71, 0xcf, 0xd8, 0xd6, + 0x56, 0x9f, 0xe0, 0xff, 00, 0xe0, 0xf9, 0x1e, 0xf6, 0x17, + 0x16, 0xab, 0x7b, 0x93, 0xd1, 0xfe, 0x67, 0x73, 0x45, 0x14, + 0x57, 0xd5, 0x9e, 0x90, 0x51, 0x45, 0x14, 00, 0x57, 0xcc, + 0xff, 00, 0xb4, 0xf5, 0xdf, 0xef, 0xd9, 0x33, 0xd1, 0x71, + 0x5f, 0x4c, 0x57, 0xc9, 0xbf, 0xb4, 0xbd, 0xd1, 0x7d, 0x52, + 0x55, 0xcf, 0xf1, 0x1a, 0xf9, 0xdc, 0xf6, 0x56, 0xc1, 0xb5, + 0xdc, 0xf1, 0xb3, 0x69, 0x72, 0xe1, 0x64, 0x7c, 0xdf, 0xac, + 0x36, 0xdb, 0x77, 0x3e, 0xd5, 0x4f, 0xf6, 0x27, 0xb6, 0xfe, + 0xd1, 0xfd, 0xb2, 0xf4, 0xc7, 0x20, 0x37, 0xd9, 0x34, 0xab, + 0xe9, 0xf9, 0xed, 0x95, 0x54, 0xcf, 0xfe, 0x3f, 0x53, 0x78, + 0x81, 0xf6, 0xd9, 0xc8, 0x7f, 0xd9, 0x35, 0x77, 0xfe, 0x9, + 0xe7, 0x69, 0xf6, 0xef, 0xda, 0xbb, 0x5c, 0xb9, 0xea, 0x2d, + 0x3c, 0x3b, 0x3f, 0xe6, 0xd3, 0xc2, 0x3f, 0xa1, 0xaf, 0x27, + 0x23, 0x8e, 0xb7, 0x3f, 0x34, 0xc8, 0x23, 0xcf, 0x9b, 0xa7, + 0xd9, 0x33, 0xf4, 0xee, 0x8a, 0x28, 0xaf, 0xb8, 0x3f, 0x64, + 0xa, 0x28, 0xa2, 0x80, 0x23, 0xb9, 0xb8, 0x8e, 0xd2, 0xde, + 0x59, 0xe5, 0x60, 0x91, 0x44, 0xa5, 0xdd, 0x8f, 0x40, 00, + 0xc9, 0x35, 0xf9, 0xe1, 0xe3, 0xcf, 0x13, 0xc9, 0xe3, 0x3f, + 0x19, 0xea, 0xfa, 0xcb, 0x9c, 0x8b, 0xbb, 0x86, 0x68, 0xfd, + 0xa3, 0x1c, 0x20, 0xff, 00, 0xbe, 0x40, 0xaf, 0xaf, 0x3f, + 0x69, 0x7f, 0x18, 0x9f, 0xa, 0x7c, 0x33, 0xbb, 0x82, 0x17, + 0xdb, 0x77, 0xaa, 0xb7, 0xd8, 0xa3, 0xf5, 0xda, 0xc0, 0x97, + 0x3f, 0xf7, 0xc8, 0x3f, 0x98, 0xaf, 0x8d, 0x7c, 0x3d, 0xa5, + 0x3e, 0xb3, 0xac, 0xd9, 0xd9, 0x46, 0x9, 0x69, 0xa4, 0x54, + 00, 0x7b, 0x9a, 0xf8, 0x7e, 0x20, 0xc4, 0x39, 0x4e, 0x18, + 0x78, 0xf4, 0xd7, 0xe6, 0xf6, 0x3e, 0xb, 0x88, 0x6b, 0xba, + 0xb5, 0xa9, 0xe1, 0x21, 0xd3, 0x57, 0xea, 0xf6, 0xfe, 0xbc, + 0xcf, 0xab, 0x3f, 0x65, 0x6f, 0x8, 0x7f, 0x65, 0x78, 0x5a, + 0x6d, 0x5e, 0x58, 0xf6, 0xcd, 0x76, 0xc5, 0x54, 0x91, 0xfc, + 0x22, 0xbd, 0xd6, 0xb2, 0xbc, 0x2d, 0xa2, 0xc7, 0xe1, 0xef, + 0xf, 0xd8, 0xe9, 0xf1, 0x28, 0x55, 0x82, 0x20, 0xbc, 0xe, + 0xfd, 0xeb, 0x56, 0xbe, 0xab, 0x5, 0x87, 0x58, 0x5c, 0x3c, + 0x29, 0x76, 0x5f, 0x8f, 0x53, 0xec, 0xb0, 0x94, 0x16, 0x1e, + 0x84, 0x69, 0x2e, 0x88, 0x28, 0xa2, 0x8a, 0xee, 0x3a, 0xc2, + 0x8a, 0x28, 0xa0, 0xf, 0xcb, 0xbf, 0xf8, 0x2d, 0x1f, 0xc6, + 0x4b, 0xfb, 0x3b, 0x6f, 0x5, 0xfc, 0x31, 0xb3, 0x73, 0x15, + 0x8d, 0xea, 0x36, 0xb5, 0xa8, 0x60, 0x90, 0x65, 0xda, 0xc6, + 0x38, 0x50, 0xf6, 0x20, 0x1d, 0xed, 0xf5, 0xb, 0xe9, 0x5f, + 0x9b, 0x5f, 0xb, 0x34, 0xfd, 0x7b, 0xc5, 0x3e, 0x3e, 0xf0, + 0xe7, 0x86, 0xb4, 0x3d, 0x52, 0xf3, 0x4f, 0xbc, 0xd5, 0xf5, + 0x8, 0x2c, 0x22, 0x92, 0xda, 0x77, 0x8f, 0x61, 0x92, 0x40, + 0x9b, 0xbe, 0x52, 0x3a, 0x67, 0x3f, 0x85, 0x7e, 0x9a, 0xff, + 00, 0xc1, 0x49, 0xec, 0xfe, 0xd, 0xfe, 0xd2, 0xba, 0x1d, + 0xa6, 0xa7, 0xe1, 0xbf, 0x8a, 0xfe, 0x12, 0xb7, 0xf8, 0x87, + 0xe1, 0x7f, 0x36, 0xd9, 0x74, 0xfb, 0xbd, 0x52, 0x28, 0x56, + 0xee, 0x2d, 0xdf, 0x3c, 0x5, 0x98, 0x80, 0xae, 0xac, 0x9, + 0x5c, 0x9c, 0x64, 0xb0, 0x38, 0xce, 0x47, 0xe5, 0xa7, 0x85, + 0xfc, 0x47, 0xa8, 0x78, 0xb, 0xc5, 0xfa, 0x56, 0xb9, 0xa6, + 0xca, 0xb1, 0xea, 0x9a, 0x3d, 0xec, 0x77, 0x70, 0x48, 0xac, + 0x1d, 0x44, 0x91, 0x38, 0x65, 0xe4, 0x1c, 0x30, 0xca, 0xf6, + 0x38, 0x22, 0xa9, 0x10, 0xf7, 0x3f, 0xa6, 0x8f, 0x9, 0x78, + 0x6a, 0xd7, 0xc1, 0xde, 0x17, 0xd2, 0xb4, 0x2b, 0x22, 0xe6, + 0xd7, 0x4e, 0xb6, 0x8e, 0xd6, 0x36, 0x91, 0x8b, 0x3b, 0x4, + 0x50, 0x37, 0x31, 0x3c, 0x92, 0x71, 0x92, 0x4f, 0x52, 0x6b, + 0x5e, 0xbe, 0x30, 0xf8, 0x1b, 0xff, 00, 0x5, 0x54, 0xf8, + 0x37, 0xf1, 0x2b, 0x43, 0xb4, 0x5f, 0x15, 0xea, 0xa7, 0xc0, + 0x3e, 0x22, 0xd8, 0x5, 0xc5, 0xa6, 0xa6, 0x8c, 0xd6, 0xc5, + 0xf1, 0xc9, 0x8e, 0x75, 0x5, 0x76, 0xfa, 0x6e, 0xda, 0x7d, + 0xab, 0xd9, 0xad, 0x7f, 0x6d, 0x3f, 0x80, 0xf7, 0x87, 0x11, + 0xfc, 0x5b, 0xf0, 0x88, 0x3f, 0xf4, 0xd3, 0x55, 0x89, 0x3f, + 0xf4, 0x22, 0x2a, 0x4b, 0x3d, 0xa6, 0x8a, 0xf3, 0x1d, 0x3f, + 0xf6, 0xa0, 0xf8, 0x3d, 0xab, 0x48, 0x12, 0xcb, 0xe2, 0x97, + 0x83, 0xee, 0x9c, 0xf4, 0x58, 0xb5, 0xcb, 0x66, 0x3f, 0xfa, + 0x1d, 0x77, 0x7a, 0xf, 0x89, 0xb4, 0x8f, 0x14, 0xda, 0x35, + 0xd6, 0x8d, 0xaa, 0xd9, 0x6a, 0xd6, 0xaa, 0xdb, 0xc, 0xd6, + 0x37, 0x9, 0x32, 0x6, 0xc6, 0x70, 0x4a, 0x92, 0x33, 0x82, + 0x3f, 0x3a, 00, 0xd3, 0xaf, 0x36, 0xf8, 0xf9, 0xe2, 0x1f, + 0xec, 0x6f, 0x2, 0x4b, 0x6b, 0x1c, 0x9b, 0x27, 0xd4, 0x24, + 0x10, 00, 0xf, 0x3b, 0x3a, 0xbf, 0xe8, 0x31, 0xff, 00, + 0x2, 0xaf, 0x49, 0xaf, 0x98, 0xff, 00, 0x68, 0x3f, 0x10, + 0x7f, 0x6a, 0xf8, 0xdf, 0xec, 0x28, 0xfb, 0xa0, 0xd3, 0xe2, + 0x11, 0xe0, 0x74, 0xde, 0xdf, 0x33, 0x7f, 0xec, 0xa3, 0xf0, + 0xaf, 0x3, 0x3c, 0xc5, 0x7d, 0x57, 0x3, 0x36, 0xb7, 0x96, + 0x8b, 0xe7, 0xff, 00, 0x2, 0xe7, 0x16, 0x32, 0xa7, 0xb3, + 0xa2, 0xfc, 0xf4, 0x3c, 0xc2, 0x8a, 0x28, 0xaf, 0xc7, 0x8f, + 0x97, 0xa, 0xb7, 0xa4, 0xe9, 0xb3, 0x6b, 0x3a, 0xa5, 0xa5, + 0x8c, 00, 0xb4, 0xd7, 0x32, 0xac, 0x4a, 00, 0xee, 0x4e, + 0x2a, 0xa5, 0x7a, 0x8f, 0xec, 0xf3, 0xa0, 0x1d, 0x4f, 0xc6, + 0xad, 0x7e, 0xe9, 0x98, 0x74, 0xf8, 0x4b, 0xee, 0x23, 0x8f, + 0x31, 0xbe, 0x55, 0x1f, 0x96, 0xe3, 0xf8, 0x57, 0x6e, 0xb, + 0xe, 0xf1, 0x58, 0x98, 0x51, 0x5d, 0x5f, 0xe1, 0xd7, 0xf0, + 0x35, 0xa5, 0xf, 0x69, 0x35, 0xe, 0xe7, 0xd2, 0x3a, 0x75, + 0x8c, 0x7a, 0x66, 0x9f, 0x6d, 0x69, 0x8, 0xdb, 0x14, 0x11, + 0xac, 0x48, 0x3d, 0x80, 0xc0, 0xfe, 0x55, 0x66, 0x8a, 0x2b, + 0xf7, 0x24, 0x94, 0x55, 0x91, 0xf6, 0x9, 0x5b, 0x40, 0xaf, + 0x11, 0xfd, 0xa6, 0xec, 0x43, 0x58, 0x68, 0x57, 0x9d, 0xd2, + 0x59, 0x62, 0x3f, 0xf0, 0x20, 0xf, 0xfe, 0xcb, 0x5e, 0xdd, + 0x5e, 0x4f, 0xfb, 0x48, 0xc3, 0xe6, 0x78, 0x26, 0xce, 0x4c, + 0x7f, 0xab, 0xbe, 0x43, 0xf9, 0xa3, 0x8a, 0xf1, 0xb3, 0xa8, + 0x73, 0xe5, 0xf5, 0x57, 0x95, 0xfe, 0xe7, 0x73, 0x93, 0x16, + 0xaf, 0x42, 0x47, 0xcd, 0x94, 0x51, 0x45, 0x7e, 0x32, 0x7c, + 0xa8, 0x56, 0xc7, 0x83, 0x6f, 0x8e, 0x9b, 0xe2, 0xdd, 0x1a, + 0xe8, 0x1c, 0x79, 0x57, 0x71, 0x31, 0x3e, 0xdb, 0x86, 0x7f, + 0x4a, 0xc7, 0xa7, 0x47, 0x21, 0x86, 0x45, 0x91, 0x7e, 0xf2, + 0x90, 0xc3, 0xf0, 0xad, 0x29, 0xcf, 0xd9, 0xce, 0x33, 0x5d, + 0x1d, 0xc7, 0x17, 0x66, 0x99, 0xf7, 0x4d, 0x15, 0x5b, 0x4c, + 0xb9, 0x17, 0xba, 0x75, 0xad, 0xc0, 0xe9, 0x2c, 0x49, 0x20, + 0xfc, 0x40, 0x35, 0x66, 0xbf, 0x7b, 0x4e, 0xe9, 0x34, 0x7d, + 0x9a, 0xd4, 0x28, 0xa2, 0x8a, 0x63, 0xa, 0x28, 0xa2, 0x80, + 0x38, 0xbf, 0x8c, 0x3a, 0xc8, 0xd1, 0x3e, 0x1e, 0x6a, 0xd2, + 0x6, 0xdb, 0x24, 0xf1, 0xfd, 0x99, 0x30, 0x79, 0x25, 0xce, + 0xe, 0x3f, 0xc, 0x9f, 0xc2, 0xbe, 0x48, 0xaf, 0x75, 0xfd, + 0xa6, 0x35, 0xa3, 0x9d, 0x1f, 0x49, 0x46, 0xf9, 0x7e, 0x7b, + 0x99, 0x14, 0x7f, 0xdf, 0x2b, 0xff, 00, 0xb3, 0x57, 0x85, + 0x57, 0xe5, 0x1c, 0x47, 0x88, 0xf6, 0xd8, 0xde, 0x45, 0xb4, + 0x12, 0x5f, 0xaf, 0xea, 0x7c, 0xde, 0x3e, 0x7c, 0xd5, 0xad, + 0xd8, 0x28, 0xa2, 0x8a, 0xf9, 0x63, 0xce, 0xa, 0xfa, 0x7b, + 0xf6, 0x7d, 0xd0, 0xff, 00, 0xb2, 0xfc, 0x8, 0x2e, 0xd9, + 0x71, 0x2d, 0xfc, 0xcd, 0x2e, 0x48, 0xe7, 0x68, 0xf9, 0x57, + 0xf9, 0x13, 0xf8, 0xd7, 0xcc, 0x71, 0x44, 0xd3, 0x4a, 0x91, + 0xa0, 0x2c, 0xee, 0x42, 0xa8, 0x1d, 0xc9, 0xe9, 0x5f, 0x6b, + 0x78, 0x67, 0x49, 0x5d, 0xb, 0xc3, 0xda, 0x6e, 0x9c, 0xbf, + 0xf2, 0xed, 0x6e, 0x91, 0x1f, 0x72, 0x14, 0x64, 0xfe, 0x75, + 0xf6, 0x9c, 0x2f, 0x43, 0x9f, 0x11, 0x3a, 0xcf, 0xec, 0xaf, + 0xc5, 0xff, 00, 0xc0, 0x3d, 0x5c, 0xbe, 0x17, 0xa8, 0xe5, + 0xd8, 0xd3, 0xa2, 0x8a, 0x2b, 0xf4, 0xc3, 0xe8, 0x2, 0x8a, + 0x28, 0xa0, 0xc, 0x3f, 0x1c, 0xdb, 0xb5, 0xd7, 0x82, 0xf5, + 0xd8, 0x50, 0x65, 0xde, 0xc6, 0x65, 00, 0x7a, 0xec, 0x35, + 0xf1, 0x87, 0x5a, 0xfb, 0xa2, 0x58, 0x96, 0x78, 0x9e, 0x37, + 0x19, 0x47, 0x52, 0xa4, 0x1e, 0xe0, 0xd7, 0xc4, 0xfe, 0x21, + 0xd2, 0x5f, 0x42, 0xd7, 0x75, 0xd, 0x3a, 0x40, 0x77, 0x5b, + 0x4e, 0xf1, 0x73, 0xdc, 0x3, 0xc1, 0xfc, 0x46, 0xd, 0x7e, + 0x7d, 0xc5, 0x54, 0x9d, 0xe9, 0x55, 0xe9, 0xaa, 0xfd, 0x4f, + 0x13, 0x32, 0x8e, 0xb1, 0x91, 0x9f, 0x45, 0x14, 0x57, 0xc0, + 0x1e, 0x28, 0x57, 0x5f, 0xf0, 0x97, 0x55, 0x5d, 0x1f, 0xe2, + 0x1e, 0x8b, 0x33, 0x9c, 0x23, 0xcd, 0xe4, 0x31, 0x3f, 0xed, + 0x82, 0xa3, 0xf5, 0x22, 0xb9, 0xa, 0x74, 0x52, 0xbc, 0x32, + 0xa4, 0x91, 0xb1, 0x57, 0x42, 0x19, 0x58, 0x75, 0x4, 0x74, + 0x35, 0xbd, 0xa, 0xae, 0x85, 0x58, 0x55, 0x5f, 0x65, 0xa7, + 0xf7, 0x15, 0x9, 0x72, 0x49, 0x4b, 0xb1, 0xf7, 0x4d, 0x15, + 0xcb, 0x7c, 0x38, 0xf1, 0xb4, 0x1e, 0x39, 0xf0, 0xcd, 0xbd, + 0xea, 0xb2, 0xad, 0xda, 0xf, 0x2e, 0xe6, 0x10, 0x79, 0x47, + 0x1f, 0xd0, 0xf5, 0x1f, 0x5a, 0xea, 0x6b, 0xf7, 0x3a, 0x35, + 0x61, 0x5e, 0x9c, 0x6a, 0xd3, 0x77, 0x4f, 0x53, 0xec, 0x63, + 0x25, 0x38, 0xa9, 0x47, 0x66, 0x14, 0x51, 0x45, 0x6c, 0x50, + 0x51, 0x45, 0x23, 0x30, 0x45, 0x2c, 0xc4, 0x2a, 0x81, 0x92, + 0x4f, 0x41, 0x40, 0x11, 0xdd, 0x5d, 0x45, 0x63, 0x6d, 0x2d, + 0xc4, 0xf2, 0x2c, 0x50, 0x44, 0x85, 0xdd, 0xd8, 0xe0, 0x2a, + 0x81, 0x92, 0x4d, 0x7c, 0x79, 0xf1, 0x7, 0xc5, 0xaf, 0xe3, + 0x5f, 0x15, 0x5e, 0x6a, 0x64, 0x15, 0x85, 0x8f, 0x97, 0x2, + 0x1f, 0xe1, 0x8d, 0x78, 0x5f, 0xcf, 0xaf, 0xd4, 0x9a, 0xef, + 0xfe, 0x36, 0x7c, 0x58, 0x4d, 0x74, 0xbe, 0x83, 0xa3, 0xcd, + 0xba, 0xc1, 0x1b, 0xfd, 0x22, 0xe5, 0x1b, 0x89, 0x88, 0xfe, + 0x11, 0xfe, 0xc8, 0xf5, 0xee, 0x7d, 0xba, 0xf8, 0xed, 0x7e, + 0x63, 0xc4, 0x39, 0x9c, 0x71, 0x33, 0x58, 0x6a, 0x2e, 0xf1, + 0x8e, 0xef, 0xbb, 0xff, 00, 0x80, 0x7c, 0xf6, 0x3b, 0x10, + 0xaa, 0x3f, 0x67, 0x1d, 0x90, 0x51, 0x45, 0x15, 0xf1, 0xa7, + 0x96, 0x14, 0x51, 0x5d, 0x67, 0xc3, 0x2f, 0x6, 0x3f, 0x8d, + 0xfc, 0x57, 0x6d, 0x66, 0xca, 0xdf, 0x63, 0x8f, 0xf7, 0xd7, + 0x2e, 0x7, 0x44, 0x1d, 0xbf, 0x13, 0x81, 0xf8, 0xfb, 0x56, + 0xd4, 0x68, 0xcf, 0x11, 0x52, 0x34, 0xa9, 0xad, 0x5b, 0xb1, + 0x51, 0x8b, 0x9c, 0x94, 0x56, 0xec, 0xf7, 0xbf, 0x81, 0x7e, + 0x17, 0x6f, 0xe, 0xf8, 0x1e, 0x19, 0xa6, 0x5d, 0xb7, 0x3a, + 0x83, 0x7d, 0xa9, 0x81, 0x1c, 0x85, 0x20, 0x4, 0x1f, 0x90, + 0xcf, 0xe3, 0x5e, 0x89, 0x4d, 0x8e, 0x35, 0x8a, 0x35, 0x44, + 0x50, 0xa8, 0xa0, 0x28, 0x51, 0xd0, 0xa, 0x75, 0x7e, 0xe3, + 0x86, 0xa1, 0x1c, 0x2d, 0x18, 0x51, 0x8e, 0xd1, 0x56, 0x3e, + 0xbe, 0x9c, 0x15, 0x38, 0x28, 0x2e, 0x81, 0x45, 0x14, 0x57, + 0x49, 0xa0, 0x51, 0x45, 0x14, 0x1, 0x53, 0x51, 0xd2, 0x2c, + 0x75, 0x78, 0x4c, 0x37, 0xd6, 0x70, 0x5e, 0x44, 0x7a, 0xa4, + 0xf1, 0x87, 0x1f, 0xad, 0x79, 0xf6, 0xbf, 0xfb, 0x3f, 0xf8, + 0x63, 0x57, 0x2d, 0x25, 0xa2, 0xcf, 0xa5, 0x4a, 0x7f, 0xe7, + 0xdd, 0xf2, 0x99, 0xff, 00, 0x75, 0xb3, 0xfa, 0x11, 0x5e, + 0x99, 0x45, 0x72, 0x57, 0xc1, 0xe1, 0xf1, 0x2a, 0xd5, 0xa0, + 0xa5, 0xfd, 0x77, 0x32, 0x9d, 0x28, 0x54, 0xf8, 0xd5, 0xcf, + 0x9b, 0x3c, 0x45, 0xfb, 0x3a, 0xeb, 0xba, 0x68, 0x69, 0x34, + 0xbb, 0x88, 0x75, 0x58, 0x87, 0x44, 0xff, 00, 0x55, 0x26, + 0x3e, 0x84, 0xe0, 0xfe, 0x75, 0xe6, 0xba, 0xb6, 0x87, 0xa8, + 0x68, 0x37, 0x3f, 0x67, 0xd4, 0x6c, 0xa7, 0xb2, 0x9b, 0xfb, + 0xb3, 0x21, 0x5c, 0xfd, 0x3d, 0x7f, 0xa, 0xfb, 0x76, 0xa9, + 0xea, 0x9a, 0x45, 0x96, 0xb7, 0x68, 0xf6, 0xb7, 0xf6, 0xb1, + 0x5d, 0xdb, 0xb7, 0x58, 0xe5, 0x50, 0xc3, 0xff, 00, 0xad, + 0x5f, 0x2f, 0x8a, 0xe1, 0x8c, 0x3d, 0x4b, 0xbc, 0x3c, 0x9c, + 0x5f, 0x6d, 0xd7, 0xf9, 0x9e, 0x75, 0x4c, 0xbe, 0x12, 0xd6, + 0xe, 0xc7, 0xc4, 0x14, 0x57, 0xa5, 0x7c, 0x60, 0xf8, 0x56, + 0xbe, 0x5, 0xb8, 0x8a, 0xfb, 0x4f, 0x2f, 0x26, 0x93, 0x72, + 0xe5, 0x70, 0xfc, 0x98, 0x5f, 0xa8, 0x5c, 0xf7, 0x4, 0x67, + 0x7, 0xda, 0xbc, 0xd6, 0xbf, 0x3c, 0xc5, 0x61, 0xaa, 0xe0, + 0xea, 0xba, 0x35, 0x55, 0x9a, 0x3c, 0x4a, 0x94, 0xe5, 0x4a, + 0x4e, 0x32, 0xdc, 0x28, 0xa2, 0x8a, 0xe5, 0x33, 0xa, 0xea, + 0x7e, 0x19, 0x78, 0x96, 0x5f, 0xb, 0x78, 0xd3, 0x4d, 0xba, + 0x46, 0x22, 0x19, 0x25, 0x10, 0x4e, 0xb9, 0xe1, 0xa3, 0x62, + 0x1, 0xcf, 0xd3, 0x83, 0xf8, 0x57, 0x2d, 0x4a, 0xac, 0x55, + 0x81, 0x7, 0x4, 0x1c, 0x82, 0x2b, 0x6a, 0x35, 0x65, 0x42, + 0xac, 0x6a, 0xc7, 0x74, 0xee, 0x54, 0x24, 0xe1, 0x25, 0x25, + 0xd0, 0xfb, 0xaa, 0x8a, 0x82, 0xc5, 0xda, 0x5b, 0x2b, 0x77, + 0x6e, 0x19, 0xa3, 0x52, 0x7e, 0xb8, 0xa9, 0xeb, 0xf7, 0x94, + 0xee, 0xae, 0x7d, 0x9a, 0xd4, 0x28, 0xa2, 0x8a, 0x60, 0x21, + 0x38, 0x15, 0xf1, 0xaf, 0xed, 0xf, 0x77, 0xe7, 0x6b, 0xb2, + 0x8f, 0x57, 0x3f, 0xce, 0xbe, 0xc8, 0x94, 0xed, 0x89, 0xcf, + 0xa2, 0x93, 0x5f, 0x10, 0x7c, 0x73, 0xb9, 0xf3, 0xbc, 0x45, + 0x2f, 0xfb, 0xed, 0xfc, 0xeb, 0xe5, 0x78, 0x86, 0x56, 0xc3, + 0xc6, 0x3d, 0xd9, 0xf3, 0xb9, 0xec, 0xb9, 0x70, 0xac, 0xf1, + 0x1f, 0x14, 0xc9, 0xb2, 0xc2, 0x6f, 0xf7, 0x4d, 0x76, 0x9f, + 0xf0, 0x4c, 0x9d, 0x3c, 0x5d, 0x7c, 0x65, 0xf8, 0x91, 0xa9, + 0x11, 0x9f, 0xb3, 0xe9, 0x96, 0xd6, 0xe1, 0xb1, 0xfd, 0xf9, + 0x59, 0x8f, 0xfe, 0x81, 0x5c, 0xf, 0x8d, 0x25, 0xd9, 0xa6, + 0x4d, 0xf4, 0x35, 0xeb, 0xff, 00, 0xf0, 0x4b, 0x2b, 0xd, + 0xf7, 0x3f, 0x15, 0x35, 0x22, 0x3e, 0xfd, 0xcd, 0x95, 0xba, + 0x9f, 0xf7, 0x52, 0x46, 0x3f, 0xfa, 0x10, 0xac, 0x72, 0x38, + 0xe9, 0x73, 0xe1, 0xb8, 0x5e, 0x3c, 0xd9, 0x95, 0x49, 0x76, + 0x47, 0xdf, 0x74, 0x51, 0x45, 0x7d, 0x81, 0xfa, 0xd8, 0x51, + 0x45, 0x66, 0x78, 0x9b, 0x5d, 0x83, 0xc3, 0x1e, 0x1e, 0xd4, + 0x75, 0x6b, 0x93, 0x88, 0x6c, 0xe0, 0x79, 0xd8, 0x67, 0x19, + 0xda, 0x33, 0x8f, 0xa9, 0xe9, 0x4a, 0x4d, 0x45, 0x36, 0xfa, + 0x13, 0x29, 0x28, 0xa7, 0x27, 0xb2, 0x3e, 0x49, 0xfd, 0xaa, + 0xfc, 0x62, 0xda, 0xef, 0xc4, 0x25, 0xd1, 0xe3, 0x72, 0x6d, + 0x34, 0x88, 0x82, 0x15, 0xc8, 0x20, 0xca, 0xe0, 0x33, 0x1f, + 0xcb, 0x68, 0xfc, 0xd, 0x27, 0xec, 0xc1, 0xe1, 0xf, 0xed, + 0xcf, 0x1b, 0xad, 0xfc, 0xd1, 0xee, 0xb7, 0xb2, 0x52, 0xf9, + 0x23, 0x8d, 0xdd, 0xab, 0xc8, 0xf5, 0x6d, 0x52, 0xe3, 0x5e, + 0xd5, 0xef, 0x35, 0x1b, 0xa7, 0x32, 0x5c, 0xdd, 0xcc, 0xd3, + 0x48, 0xc7, 0xd5, 0x8e, 0x6b, 0xec, 0x9f, 0xd9, 0xaf, 0xc2, + 0x3f, 0xf0, 0x8f, 0x78, 0x12, 0x3b, 0xb9, 0x13, 0x6d, 0xc5, + 0xe3, 0x17, 0x39, 0xfe, 0xef, 0x6a, 0xfc, 0xef, 0x8, 0x9e, + 0x63, 0x99, 0x7b, 0x49, 0x6d, 0x7b, 0xfc, 0x96, 0xdf, 0xa1, + 0xf9, 0xd6, 0x5c, 0x9e, 0x63, 0x99, 0x4b, 0x11, 0x2d, 0x93, + 0xbf, 0xf9, 0x1e, 0xbb, 0x45, 0x14, 0x57, 0xe8, 0xa7, 0xe8, + 0xe1, 0x45, 0x79, 0xef, 0xed, 0x1, 0xf1, 0x6a, 0xcb, 0xe0, + 0x67, 0xc1, 0xbf, 0x15, 0xf8, 0xde, 0xf9, 0x94, 0x2e, 0x93, + 0x62, 0xf2, 0xc2, 0x8d, 0xd2, 0x59, 0xc8, 0xdb, 0xa, 0x7f, + 0xc0, 0x9c, 0xa8, 0xfc, 0x6b, 0xf2, 0x66, 0xc3, 0xfe, 0xb, + 0x29, 0xf1, 0xba, 0xdd, 0x97, 0xed, 0x5a, 0x2f, 0x83, 0xae, + 0xd0, 0x75, 0x2, 0xc2, 0xe2, 0x32, 0x7f, 0x11, 0x39, 0xfe, + 0x54, 0xa, 0xf6, 0x3f, 0x6a, 0x2b, 0xc7, 0x7f, 0x6b, 0xaf, + 0x8c, 0xf0, 0x7c, 0x4, 0xfd, 0x9e, 0xbc, 0x63, 0xe2, 0xe7, + 0x90, 0x2d, 0xe4, 0x36, 0x8d, 0x6d, 0x60, 0xb9, 0xc1, 0x7b, + 0xa9, 0x7f, 0x77, 0x10, 0x1f, 0x46, 0x6d, 0xc7, 0xd9, 0x4d, + 0x5f, 0xfd, 0x98, 0xbe, 0x21, 0x78, 0xaf, 0xe2, 0xc7, 0xc1, + 0x1f, 0xc, 0xf8, 0xc3, 0xc6, 0x5a, 0x5d, 0x96, 0x8b, 0xac, + 0x6b, 0x50, 0x7d, 0xb1, 0x6c, 0x6c, 0x43, 0xec, 0x8e, 0x6, + 0x3f, 0xba, 0x27, 0x79, 0x27, 0x2c, 0xb8, 0x6f, 0xf8, 0x10, + 0x15, 0x6f, 0xe3, 0x9f, 0xec, 0xf9, 0xe0, 0xaf, 0xda, 0x37, + 0xc3, 0x16, 0x9e, 0x1e, 0xf1, 0xd5, 0x85, 0xce, 0xa5, 0xa4, + 0xdb, 0x5c, 0x8b, 0xc8, 0xe0, 0xb7, 0xbc, 0x96, 0xdf, 0xf7, + 0xa1, 0x59, 0x43, 0x13, 0x1b, 0x2, 0x70, 0x19, 0xb8, 0x3c, + 0x73, 0x40, 0xcf, 0xe6, 0xc6, 0x59, 0x5e, 0x79, 0x5e, 0x49, + 0x18, 0xbc, 0x8e, 0x4b, 0x33, 0x31, 0xc9, 0x24, 0xf5, 0x26, + 0x9b, 0x5f, 0xba, 0x57, 0x5f, 0xf0, 0x49, 0xbf, 0xd9, 0xda, + 0xe1, 0x8, 0x8f, 0x40, 0xd6, 0x2d, 0x4f, 0xf7, 0xa2, 0xd6, + 0x67, 0x27, 0xff, 00, 0x1e, 0x26, 0xb0, 0x6f, 0x7f, 0xe0, + 0x8f, 0x3f, 0x2, 0x6e, 0x3, 0x79, 0x17, 0x5e, 0x2a, 0xb4, + 0x27, 0xa6, 0xdd, 0x4a, 0x36, 0x3, 0xf3, 0x8a, 0xaa, 0xe4, + 0x72, 0xb3, 0xf1, 0x2e, 0x8a, 0xfd, 0x8a, 0xd4, 0x7f, 0xe0, + 0x8b, 0x1f, 0xc, 0x27, 0x2c, 0x6c, 0xfc, 0x6d, 0xe2, 0xab, + 0x4f, 0x40, 0xff, 00, 0x67, 0x90, 0xf, 0xfc, 0x86, 0xd, + 0x72, 0xf7, 0xdf, 0xf0, 0x44, 0x8d, 0x5, 0xd9, 0xbe, 0xc5, + 0xf1, 0x4b, 0x51, 0x88, 0x76, 0x13, 0xe9, 0x51, 0xbf, 0xf2, + 0x91, 0x68, 0xb8, 0xb9, 0x59, 0xf9, 0x39, 0x8f, 0x6a, 0xfe, + 0x88, 0x7f, 0x62, 0xf, 0x82, 0xb1, 0xfc, 0x7, 0xfd, 0x9a, + 0xbc, 0x1f, 0xe1, 0xd6, 0x89, 0x53, 0x53, 0xb8, 0xb6, 0x1a, + 0x96, 0xa2, 0xc0, 0x60, 0xb5, 0xcc, 0xe0, 0x3b, 0x3, 0xfe, + 0xe8, 0x2a, 0x9f, 0x45, 0x15, 0xf1, 0xe7, 0x83, 0xff, 00, + 0xe0, 0x8b, 0xe9, 0xe1, 0xcf, 0x1e, 0x68, 0x3a, 0xad, 0xff, + 00, 0xc4, 0x68, 0x75, 0x8d, 0x16, 0xc6, 0xfa, 0x1b, 0x9b, + 0xab, 0x6, 0xd2, 0x8c, 0x4f, 0x71, 0x1a, 0x38, 0x63, 0x1e, + 0xef, 0x34, 0x81, 0xbb, 0x18, 0xe9, 0xde, 0xbf, 0x4e, 0x95, + 0x42, 0x28, 0x55, 0x1, 0x54, 0xc, 00, 0x3a, 0x1, 0x49, + 0x94, 0x95, 0x8a, 0x9a, 0xbe, 0xa5, 0x16, 0x8f, 0xa5, 0x5d, + 0xdf, 0x4c, 0x40, 0x8a, 0xda, 0x26, 0x95, 0x89, 0xf4, 0x3, + 0x35, 0xf1, 0x4e, 0xa5, 0xa8, 0x4d, 0xaa, 0xea, 0x17, 0x37, + 0xb7, 0xd, 0xbe, 0x7b, 0x89, 0x1a, 0x57, 0x3e, 0xe4, 0xe4, + 0xd7, 0xd6, 0x7f, 0x14, 0xf4, 0xd, 0x5f, 0xc5, 0x1e, 0x13, + 0x97, 0x4b, 0xd1, 0xcc, 0x2b, 0x2d, 0xc4, 0x8a, 0x25, 0x33, + 0x39, 0x51, 0xe5, 0x8e, 0x48, 0x1c, 0x1e, 0xa4, 0xf, 0xd6, + 0xbc, 0x32, 0x4f, 0xd9, 0xfb, 0xc5, 0xc8, 0x38, 0x82, 0xd2, + 0x4f, 0xf7, 0x6e, 0x7, 0xf5, 0xc5, 0x7c, 0x17, 0x11, 0x51, + 0xc5, 0x62, 0xaa, 0x42, 0x9d, 0x1a, 0x6d, 0xc6, 0x2a, 0xfa, + 0x2e, 0xaf, 0xfc, 0x8f, 0x23, 0x1d, 0x1a, 0x95, 0x24, 0x94, + 0x62, 0xda, 0x47, 0x9b, 0x51, 0x5d, 0xec, 0xdf, 0x3, 0x7c, + 0x67, 0xf, 0xfc, 0xc2, 0x84, 0x9f, 0xee, 0x5c, 0x46, 0x7f, + 0xf6, 0x6a, 0xa5, 0x2f, 0xc2, 0x2f, 0x18, 0x43, 0xf7, 0xb4, + 0x2b, 0x83, 0xfe, 0xe9, 0x56, 0xfe, 0x46, 0xbe, 0x2a, 0x58, + 0xc, 0x5c, 0x77, 0xa5, 0x2f, 0xb9, 0x9e, 0x4b, 0xa3, 0x55, + 0x7d, 0x97, 0xf7, 0x1c, 0x7d, 0x7d, 0x3f, 0xfb, 0x3f, 0xe8, + 0x1f, 0xd9, 0x3e, 0x4, 0x4b, 0xb7, 0x4d, 0xb3, 0x6a, 0x12, + 0xb4, 0xc4, 0x91, 0xce, 0xc1, 0xf2, 0xaf, 0xf2, 0x27, 0xf1, + 0xaf, 0x9, 0xb7, 0xf8, 0x63, 0xe2, 0x79, 0x6f, 0x60, 0xb7, + 0x93, 0x44, 0xbd, 0x84, 0x49, 0x22, 0xa1, 0x91, 0xa1, 0x3b, + 0x57, 0x27, 0x19, 0x27, 0xd0, 0x57, 0xd7, 0x3a, 0x75, 0x8c, + 0x5a, 0x5d, 0x85, 0xb5, 0x9c, 0xb, 0xb6, 0x18, 0x23, 0x58, + 0x90, 0x7a, 00, 0x30, 0x2b, 0xeb, 0x38, 0x6b, 0x5, 0x38, + 0xd7, 0x9d, 0x7a, 0xb1, 0x6b, 0x95, 0x59, 0x5d, 0x5b, 0x57, + 0xff, 00, 0x3, 0xf3, 0x3d, 0x2c, 0x5, 0x26, 0xa6, 0xe7, + 0x25, 0xb1, 0x66, 0x8a, 0x28, 0xaf, 0xd1, 0x4f, 0x74, 0x2b, + 0xcd, 0x7f, 0x68, 0x38, 0xbc, 0xcf, 0x87, 0x53, 0x36, 0x3e, + 0xe5, 0xcc, 0x4d, 0xfa, 0xe3, 0xfa, 0xd7, 0xa5, 0x57, 0x3, + 0xf1, 0xce, 0x2f, 0x37, 0xe1, 0x9e, 0xa8, 0x7f, 0xb8, 0xd1, + 0x37, 0xfe, 0x44, 0x5f, 0xf1, 0xaf, 0x37, 0x32, 0x5c, 0xd8, + 0x2a, 0xcb, 0xfb, 0xaf, 0xf2, 0x39, 0xf1, 0xa, 0xf4, 0xa5, + 0xe8, 0x7c, 0xa5, 0x45, 0x14, 0x57, 0xe2, 0x27, 0xc9, 0x5, + 0x14, 0x51, 0x40, 0x1f, 0x64, 0x7c, 0x3a, 0xba, 0xfb, 0x67, + 0x80, 0xf4, 0x9, 0x49, 0xc9, 0x36, 0x51, 0x3, 0xf5, 0xa, + 0x7, 0xf4, 0xae, 0x8e, 0xb8, 0x4f, 0x82, 0x17, 0x86, 0xf3, + 0xe1, 0xa6, 0x95, 0x93, 0x93, 0x17, 0x99, 0x11, 0xfc, 0x1d, + 0xb1, 0xfa, 0x62, 0xbb, 0xba, 0xfd, 0xd3, 0x5, 0x3f, 0x69, + 0x86, 0xa5, 0x3e, 0xf1, 0x5f, 0x91, 0xf6, 0x14, 0x5f, 0x35, + 0x38, 0xbf, 0x24, 0x14, 0x51, 0x45, 0x76, 0x1a, 0x85, 0x14, + 0x56, 0x7f, 0x88, 0x35, 0x68, 0xf4, 0x1d, 0xe, 0xff, 00, + 0x51, 0x97, 0xee, 0x5a, 0xc2, 0xf2, 0x9f, 0x7c, 0xe, 0x5, + 0x4c, 0xa4, 0xa1, 0x17, 0x29, 0x6c, 0x84, 0xdd, 0x95, 0xd9, + 0xf2, 0xbf, 0xc6, 0xd, 0x78, 0xf8, 0x83, 0xe2, 0x6, 0xa9, + 0x20, 0x6d, 0xd0, 0xdb, 0xbf, 0xd9, 0x63, 0xfa, 0x27, 0x7, + 0xff, 00, 0x1e, 0xdc, 0x7f, 0x1a, 0xe3, 0x2a, 0x4b, 0x89, + 0xde, 0xea, 0x79, 0x66, 0x90, 0xee, 0x92, 0x46, 0x2e, 0xc7, + 0xd4, 0x93, 0x93, 0x51, 0xd7, 0xe1, 0x38, 0x8a, 0xcf, 0x11, + 0x5a, 0x75, 0x65, 0xf6, 0x9b, 0x67, 0xc7, 0x4e, 0x4e, 0x72, + 0x72, 0x7d, 0x42, 0x8a, 0x28, 0xae, 0x72, 0xe, 0xb7, 0xe1, + 0x46, 0x8f, 0xfd, 0xb7, 0xf1, 0x7, 0x46, 0x81, 0x97, 0x7c, + 0x69, 0x37, 0x9e, 0xe3, 0xb6, 0x10, 0x16, 0xfe, 0x60, 0x57, + 0xd7, 0xd5, 0xf3, 0xdf, 0xec, 0xd1, 0xa3, 0xf9, 0xfa, 0xd6, + 0xad, 0xa9, 0xb2, 0xf1, 0x6f, 0xa, 0xc0, 0x87, 0xdd, 0xce, + 0x4f, 0xe8, 0xbf, 0xad, 0x7d, 0x9, 0x5f, 0xaa, 0xf0, 0xd5, + 0xf, 0x67, 0x82, 0xf6, 0x8f, 0x79, 0x36, 0xfe, 0x4b, 0x43, + 0xe8, 0xf0, 0x10, 0xe5, 0xa5, 0xcd, 0xdc, 0x28, 0xa2, 0x8a, + 0xfa, 0xb3, 0xd2, 0xa, 0x28, 0xa2, 0x80, 0xa, 0xf9, 0xdb, + 0xf6, 0x88, 0xf0, 0x69, 0xd3, 0xf5, 0x98, 0x7c, 0x41, 0x6e, + 0x9f, 0xe8, 0xf7, 0x98, 0x8e, 0x7c, 0xf, 0xbb, 0x28, 0x1c, + 0x1f, 0xc4, 0xf, 0xfc, 0x77, 0xde, 0xbe, 0x89, 0xac, 0xdf, + 0x10, 0xe8, 0x36, 0x9e, 0x27, 0xd1, 0xae, 0xb4, 0xcb, 0xd4, + 0xdf, 0x6f, 0x70, 0xbb, 0x5b, 0x1d, 0x54, 0xf5, 0x4, 0x7b, + 0x83, 0xcd, 0x79, 0x59, 0x9e, 0x9, 0x63, 0xf0, 0xd2, 0xa3, + 0xd7, 0x75, 0xeb, 0xfd, 0x68, 0x73, 0x62, 0x28, 0xfb, 0x6a, + 0x6e, 0x3d, 0x4f, 0x89, 0xa8, 0xae, 0x8b, 0xc7, 0x1e, 0x8, + 0xbf, 0xf0, 0x2e, 0xb5, 0x25, 0x95, 0xe2, 0x16, 0x88, 0x92, + 0x60, 0xb8, 0x3, 0xe5, 0x95, 0x3d, 0x47, 0xbf, 0xa8, 0xed, + 0x5c, 0xed, 0x7e, 0x33, 0x56, 0x94, 0xe8, 0xcd, 0xd3, 0xa8, + 0xac, 0xd1, 0xf2, 0xb2, 0x8b, 0x8b, 0xe5, 0x96, 0xe1, 0x45, + 0x14, 0x56, 0x44, 0x9b, 0x7e, 0x12, 0xf1, 0x86, 0xa7, 0xe0, + 0xbd, 0x51, 0x6f, 0xb4, 0xd9, 0xb6, 0x3f, 0xdd, 0x92, 0x36, + 0xe5, 0x25, 0x5f, 0x46, 0x15, 0xf4, 0x1f, 0x85, 0x3e, 0x3e, + 0x78, 0x7b, 0x5d, 0x44, 0x8f, 0x50, 0x66, 0xd1, 0xee, 0xb8, + 0x4, 0x4f, 0xcc, 0x44, 0xfb, 0x38, 0xe9, 0xf8, 0xe2, 0xbe, + 0x61, 0xa2, 0xbd, 0xac, 0x6, 0x6d, 0x89, 0xcb, 0xfd, 0xda, + 0x6e, 0xf1, 0xec, 0xf6, 0xff, 00, 0x80, 0x75, 0x51, 0xc4, + 0xd4, 0xa1, 0xa4, 0x76, 0xec, 0x7d, 0xb7, 0x69, 0xe2, 0xd, + 0x2e, 0xfd, 0x3, 0x5b, 0x6a, 0x36, 0x97, 0xa, 0x46, 0x73, + 0x1c, 0xea, 0xdf, 0xc8, 0xd4, 0xb3, 0x6a, 0xf6, 0x36, 0xeb, + 0xba, 0x5b, 0xdb, 0x78, 0x97, 0xd5, 0xe5, 0x50, 0x3f, 0x9d, + 0x7c, 0x3f, 0x8a, 0x31, 0x5f, 0x46, 0xb8, 0xae, 0x76, 0xd6, + 0x8e, 0xbe, 0xbf, 0xf0, 0xe, 0xff, 00, 0xed, 0x27, 0xfc, + 0xbf, 0x89, 0xf5, 0x9f, 0x88, 0xbe, 0x32, 0xf8, 0x5b, 0xc3, + 0xb1, 0x9c, 0xea, 0x2b, 0x7f, 0x38, 0xe9, 0xd, 0x96, 0x24, + 0x3f, 0x98, 0xe0, 0x7e, 0x26, 0xbc, 0x47, 0xe2, 0x7, 0xc6, + 0xad, 0x5b, 0xc6, 0x4b, 0x25, 0xa5, 0xa8, 0x3a, 0x66, 0x96, + 0xc0, 0xab, 0x43, 0x1b, 0x65, 0xe5, 0x1f, 0xed, 0xb7, 0xa7, + 0xb0, 0xe3, 0xeb, 0x5e, 0x75, 0x45, 0x78, 0x98, 0xdc, 0xf7, + 0x17, 0x8c, 0x8b, 0x85, 0xf9, 0x62, 0xfa, 0x2f, 0xf3, 0x39, + 0x2a, 0xe3, 0x2a, 0xd5, 0x56, 0xd9, 0x5, 0x14, 0x51, 0x5f, + 0x3a, 0x70, 0x85, 0x14, 0x55, 0x8b, 0xd, 0x3e, 0xe7, 0x55, + 0xbc, 0x86, 0xd2, 0xd2, 0x17, 0xb8, 0xb9, 0x95, 0x82, 0xa4, + 0x68, 0x32, 0x58, 0xd3, 0x49, 0xc9, 0xd9, 0x6e, 0x1b, 0x89, + 0x65, 0x65, 0x3e, 0xa3, 0x77, 0xd, 0xad, 0xb4, 0x4d, 0x35, + 0xc4, 0xcc, 0x11, 0x23, 0x41, 0x92, 0xc4, 0xf6, 0xaf, 0xad, + 0x3e, 0x18, 0xf8, 0x6, 0x2f, 00, 0xf8, 0x7d, 0x6d, 0xdb, + 0x64, 0x9a, 0x84, 0xe7, 0xcc, 0xb9, 0x99, 0x7b, 0xb7, 0x65, + 0x1e, 0xc3, 0xfc, 0x4f, 0x7a, 0xc6, 0xf8, 0x4b, 0xf0, 0x9a, + 0x2f, 0x4, 0x5b, 0xfd, 0xbf, 0x50, 0x9, 0x36, 0xb5, 0x2a, + 0xe0, 0x95, 0x39, 0x58, 0x14, 0xff, 00, 0xa, 0xfb, 0xfa, + 0x9f, 0xc3, 0xeb, 0xe9, 0x35, 0xfa, 0x86, 0x47, 0x94, 0x3c, + 0x1a, 0xfa, 0xc5, 0x75, 0xef, 0xbd, 0x97, 0x65, 0xfe, 0x67, + 0xd0, 0xe0, 0xf0, 0xbe, 0xcb, 0xdf, 0x9e, 0xff, 00, 0x90, + 0x51, 0x45, 0x23, 0x30, 0x55, 0x24, 0x9c, 0x1, 0xc9, 0x35, + 0xf5, 0xe7, 0xa8, 0x71, 0xba, 0xef, 0xc5, 0x8d, 0xf, 0xc3, + 0x5e, 0x29, 0xfe, 0xc4, 0xd4, 0x64, 0x7b, 0x77, 0xf2, 0x96, + 0x43, 0x73, 0xb7, 0x31, 0xa9, 0x39, 0xf9, 0x5b, 0x1c, 0x8e, + 0x30, 0x73, 0x8c, 0x73, 0x5d, 0x55, 0x8e, 0xa3, 0x6b, 0xaa, + 0x40, 0xb3, 0xd9, 0xdc, 0xc5, 0x75, 0xb, 0x72, 0x24, 0x85, + 0xc3, 0x29, 0xfc, 0x45, 0x7c, 0x75, 0xe3, 0x8d, 0x78, 0xf8, + 0x9b, 0xc5, 0xba, 0xa6, 0xa5, 0x9c, 0xa4, 0xd3, 0xb7, 0x97, + 0xfe, 0xe0, 0xe1, 0x7f, 0x40, 0x2a, 0x86, 0x93, 0xae, 0x6a, + 0x1a, 0xd, 0xc8, 0xb8, 0xd3, 0xaf, 0x67, 0xb2, 0x97, 0xfb, + 0xd0, 0xb9, 0x5c, 0xfd, 0x7d, 0x7f, 0x1a, 0xfc, 0xf5, 0x71, + 0x3c, 0xa9, 0xd7, 0x9c, 0x67, 0xe, 0x68, 0x5d, 0xda, 0xda, + 0x3b, 0x7e, 0xbf, 0x81, 0xe1, 0xac, 0xc1, 0xa9, 0xb4, 0xd5, + 0xd1, 0xf6, 0xed, 0x15, 0xf3, 0x26, 0x8d, 0xfb, 0x43, 0x78, + 0x9f, 0x4e, 0xda, 0xb7, 0x82, 0xd7, 0x53, 0x8c, 0x75, 0xf3, + 0x63, 0xd8, 0xe7, 0xf1, 0x5c, 0xf, 0xd2, 0xbb, 0x6d, 0x2f, + 0xf6, 0x96, 0xd2, 0xa6, 0x55, 0x1a, 0x86, 0x95, 0x77, 0x6c, + 0xdd, 0xcc, 0xc, 0xb2, 0x2f, 0xeb, 0xb4, 0xd7, 0xd0, 0x51, + 0xcf, 0xf0, 0x15, 0xb7, 0x9f, 0x2b, 0xf3, 0x5f, 0xd2, 0x3b, + 0x61, 0x8d, 0xa3, 0x2e, 0xb6, 0x3d, 0x96, 0x8a, 0xf3, 0xcb, + 0x5f, 0x8f, 0x5e, 0xe, 0xb8, 0xc6, 0xeb, 0xe9, 0xad, 0xcf, + 0xa4, 0xb6, 0xef, 0xfd, 0x1, 0xad, 0x8, 0xbe, 0x31, 0x78, + 0x3a, 0x51, 0xc6, 0xb9, 0x2, 0xff, 00, 0xbc, 0xae, 0x3f, + 0x98, 0xaf, 0x4a, 0x39, 0x86, 0xe, 0x7f, 0xd, 0x58, 0xfd, + 0xe8, 0xe8, 0x55, 0xe9, 0x3d, 0xa4, 0xbe, 0xf3, 0xb3, 0xa2, + 0xb8, 0xa9, 0xfe, 0x32, 0xf8, 0x36, 0x1, 0x93, 0xad, 0xc4, + 0xff, 00, 0xf5, 0xce, 0x37, 0x6f, 0xe4, 0x2b, 0x9b, 0xd7, + 0x7f, 0x68, 0xcd, 0x2, 0xca, 0x16, 0x1a, 0x65, 0xbd, 0xce, + 0xa3, 0x3f, 0xf0, 0xee, 0x5f, 0x2a, 0x3f, 0xc4, 0x9e, 0x7f, + 0x4a, 0x8a, 0x99, 0x9e, 0xa, 0x92, 0xbc, 0xaa, 0xc7, 0xef, + 0xbf, 0xe4, 0x29, 0x62, 0x29, 0x45, 0x5d, 0xc9, 0x16, 0xbf, + 0x68, 0x6d, 0x4a, 0xde, 0xd7, 0xc0, 0x46, 0xd6, 0x42, 0x3e, + 0xd1, 0x75, 0x71, 0x18, 0x89, 0x7b, 0xfc, 0xa7, 0x73, 0x1f, + 0xc8, 0x63, 0xf1, 0xaf, 0x98, 0xeb, 0x7b, 0xc6, 0x3e, 0x35, + 0xd4, 0xfc, 0x71, 0xaa, 0x7d, 0xb7, 0x52, 0x90, 0x12, 0xa3, + 0x6c, 0x50, 0xc6, 0x30, 0x91, 0xaf, 0xa0, 0x1f, 0xd7, 0xad, + 0x60, 0xd7, 0xe5, 0x99, 0xbe, 0x3a, 0x38, 0xfc, 0x53, 0xab, + 0x5, 0xee, 0xa5, 0x64, 0x7c, 0xe6, 0x26, 0xb2, 0xad, 0x53, + 0x99, 0x6c, 0x14, 0x51, 0x45, 0x78, 0xa7, 0x28, 0x55, 0xcd, + 0x1e, 0xc5, 0xb5, 0x3d, 0x5e, 0xca, 0xcd, 0x46, 0x5a, 0xe2, + 0x74, 0x88, 0x1, 0xfe, 0xd3, 0x1, 0xfd, 0x6a, 0x9d, 0x7a, + 0x77, 0xc0, 0x1f, 0xa, 0x9d, 0x73, 0xc6, 0x1f, 0xda, 0x12, + 0xa9, 0x36, 0xda, 0x6a, 0xf9, 0xb9, 0xec, 0x64, 0x3c, 0x20, + 0xfe, 0x67, 0xf0, 0x15, 0xdb, 0x82, 0xc3, 0xcb, 0x15, 0x88, + 0x85, 0x18, 0xf5, 0x7f, 0x87, 0x5f, 0xc0, 0xd6, 0x94, 0x1d, + 0x49, 0xa8, 0xae, 0xa7, 0xd3, 0x68, 0xa1, 0x14, 0x28, 0xe8, + 0x6, 0x29, 0xd4, 0x51, 0x5f, 0xb9, 0x9f, 0x60, 0x14, 0x51, + 0x45, 00, 0x56, 0xd4, 0x5f, 0xcb, 0xb0, 0xb8, 0x6e, 0x98, + 0x43, 0xfc, 0xab, 0xe1, 0x1f, 0x8b, 0xd7, 0x1e, 0x77, 0x88, + 0xe5, 0xef, 0xf3, 0x1f, 0xe7, 0x5f, 0x72, 0xf8, 0x92, 0x5f, + 0x27, 0x43, 0xbc, 0x6e, 0x98, 0x8c, 0xd7, 0xc1, 0x5f, 0x12, + 0xa6, 0xf3, 0xbc, 0x45, 0x3f, 0xb3, 0x1a, 0xf8, 0xce, 0x22, + 0x97, 0xbb, 0x4e, 0x3e, 0x67, 0xc9, 0xf1, 0xc, 0xad, 0x41, + 0x23, 0xc8, 0x3e, 0x20, 0x4b, 0xb3, 0x4a, 0x9b, 0xe8, 0x6b, + 0xe9, 0x1f, 0xf8, 0x25, 0xa6, 0x9e, 0x23, 0xf8, 0x57, 0xe3, + 0x5b, 0xfc, 0x7c, 0xd7, 0x5e, 0x20, 0x64, 0xcf, 0xb2, 0x41, + 0x1f, 0xff, 00, 0x14, 0x6b, 0xe6, 0x1f, 0x89, 0x93, 0x6c, + 0xd2, 0x65, 0xfa, 0x1f, 0xe5, 0x5f, 0x60, 0x7f, 0xc1, 0x32, + 0x6c, 0x3e, 0xcd, 0xfb, 0x35, 0x1b, 0xad, 0xb8, 0x37, 0xba, + 0xe5, 0xec, 0xd9, 0xf5, 00, 0xaa, 0x7f, 0xec, 0x95, 0xd9, + 0x92, 0xc6, 0xd4, 0xcf, 0x99, 0xe1, 0x18, 0xdf, 0x13, 0x5e, + 0x7e, 0x87, 0xd6, 0x74, 0x51, 0x45, 0x7d, 0x39, 0xfa, 0x90, + 0x57, 0x82, 0xfe, 0xd6, 0xde, 0x35, 0x3a, 0x3f, 0x84, 0x6d, + 0x3c, 0x3f, 0x3, 0x62, 0x7d, 0x56, 0x4d, 0xd2, 0xe0, 0xf2, + 0x22, 0x42, 0xf, 0xea, 0xd8, 0x1f, 0x81, 0xaf, 0x7a, 0xaf, + 0x85, 0xbf, 0x68, 0x3f, 0x1a, 0x1f, 0x1a, 0x7c, 0x4b, 0xd4, + 0x1a, 0x29, 0x4, 0x96, 0x5a, 0x79, 0xfb, 0x15, 0xbe, 0xd2, + 0x70, 0x42, 0x9f, 0x98, 0xfe, 0x2d, 0x9f, 0xc8, 0x57, 0x85, + 0x9c, 0xe2, 0x3d, 0x86, 0x15, 0xa5, 0xbc, 0xb4, 0xff, 00, + 0x33, 0xe7, 0xb3, 0xdc, 0x4f, 0xd5, 0xf0, 0x6e, 0x29, 0xeb, + 0x2d, 0x3f, 0xcf, 0xf0, 0x39, 0x5f, 0x2, 0xf8, 0x7e, 0x4f, + 0x12, 0xf8, 0xa3, 0x4f, 0xd3, 0xe3, 0x5d, 0xde, 0x6c, 0xaa, + 0xf, 0xd3, 0x3c, 0xd7, 0xe8, 0x46, 0x95, 0xa7, 0xc7, 0xa5, + 0x69, 0xd6, 0xf6, 0x91, 00, 0xb1, 0xc2, 0x81, 00, 0x1e, + 0xd5, 0xf2, 0xef, 0xec, 0x9d, 0xe0, 0xff, 00, 0xb6, 0x6b, + 0x77, 0x7a, 0xd4, 0xc9, 0x98, 0xed, 0xd3, 0x6c, 0x64, 0x8e, + 0x37, 0x1a, 0xfa, 0xb6, 0xb8, 0xb8, 0x7f, 0xf, 0xc9, 0x46, + 0x55, 0xde, 0xf2, 0xfc, 0x91, 0x87, 0xf, 0xe1, 0xbd, 0x8e, + 0x1b, 0xda, 0x3d, 0xe5, 0xf9, 0x5, 0x14, 0x51, 0x5f, 0x54, + 0x7d, 0x41, 0xf9, 0x87, 0xff, 00, 0x5, 0x9e, 0xf8, 0xdd, + 0x1d, 0xb6, 0x8b, 0xe1, 0x2f, 0x85, 0x76, 0x17, 0x2c, 0x2e, + 0x2e, 0x65, 0xfe, 0xda, 0xd4, 0xe3, 0x46, 0xc0, 0xf2, 0x97, + 0x72, 0x40, 0x8d, 0xeb, 0x96, 0xde, 0xd8, 0xff, 00, 0x61, + 0x4d, 0x7e, 0x72, 0xfe, 0xcf, 0x7f, 0xa, 0xe5, 0xf8, 0xdb, + 0xf1, 0xb3, 0xc1, 0xbe, 0x7, 0x89, 0xfc, 0xb5, 0xd6, 0x75, + 0x8, 0xe0, 0x99, 0xf3, 0x8d, 0xb0, 0x8c, 0xbc, 0xa4, 0x7b, + 0x88, 0xd5, 0xc8, 0xf7, 0xaf, 0x55, 0xff, 00, 0x82, 0x90, + 0x6b, 0xf7, 0x9a, 0xff, 00, 0xed, 0x9f, 0xf1, 0x1c, 0xdd, + 0xc8, 0xce, 0xb6, 0x77, 0x30, 0x59, 0x40, 0xac, 0x73, 0xb2, + 0x34, 0xb7, 0x8c, 00, 0x3d, 0xb2, 0x58, 0xff, 00, 0xc0, + 0x8d, 0x7c, 0xfb, 0xe1, 0x5f, 0x15, 0x6a, 0xfe, 0x7, 0xf1, + 0x1e, 0x9d, 0xaf, 0xe8, 0x3a, 0x84, 0xfa, 0x56, 0xb3, 0xa7, + 0xcc, 0xb7, 0x16, 0xb7, 0x96, 0xcd, 0xb6, 0x48, 0x9c, 0x74, + 0x20, 0xff, 00, 0x9c, 0xf4, 0xaa, 0x33, 0x6f, 0x53, 0xfa, + 0x71, 0x51, 0xa7, 0xf8, 0x4b, 0xc3, 0xc0, 0x7c, 0x96, 0x7a, + 0x5e, 0x99, 0x6b, 0x8f, 0x45, 0x8a, 0x18, 0xd3, 0xf9, 0x5, + 0x5f, 0xd2, 0xbf, 0xe, 0xbe, 0x24, 0x7f, 0xc1, 0x4e, 0x7e, + 0x37, 0x6a, 0x3f, 0x13, 0x7c, 0x4b, 0xa8, 0xf8, 0x57, 0xc6, + 0xd3, 0xe9, 0x9e, 0x1a, 0x9a, 0xfe, 0x66, 0xd3, 0x74, 0xe3, + 0x67, 0x6e, 0xe9, 0xd, 0xbe, 0xe2, 0x23, 0x1f, 0x34, 0x64, + 0xe7, 0x68, 0x4, 0xe4, 0x9e, 0x49, 0xa8, 0x3c, 0x61, 0xff, + 00, 0x5, 0x45, 0xf8, 0xd9, 0xe3, 0xcf, 0x86, 0xda, 0xd7, + 0x83, 0x35, 0x89, 0xf4, 0x49, 0xac, 0xf5, 0x6b, 0x17, 0xb0, + 0xb9, 0xbe, 0x86, 0xc5, 0xa2, 0xba, 0xf2, 0xdd, 0x76, 0xb1, + 0xc, 0xae, 0x14, 0x31, 0x19, 0x19, 0xdb, 0xdc, 0xd7, 0xc8, + 0xb4, 0x92, 0x1b, 0x7d, 0x8f, 0xdf, 0x7f, 0xf8, 0x27, 0x7f, + 0xc4, 0x8f, 0x88, 0xff, 00, 0x18, 0xbe, 0x1, 0x47, 0xe3, + 0x6f, 0x88, 0xfa, 0xc2, 0xea, 0xb7, 0x7a, 0xad, 0xf4, 0xa3, + 0x4f, 0x9, 0x69, 0x1d, 0xb8, 0x8e, 0xda, 0x33, 0xe5, 0xe4, + 0x84, 0x51, 0x92, 0xce, 0xae, 0x72, 0x7b, 0x1, 0x5f, 0x50, + 0xd7, 0xe3, 0xaf, 0xc3, 0xf, 0xf8, 0x2b, 0xf6, 0xa3, 0xf0, + 0xbf, 0xc0, 0xfa, 0x7, 0x85, 0x34, 0xff, 00, 0x84, 0xda, + 0x50, 0xd2, 0xb4, 0x6b, 0x38, 0xac, 0xa0, 0x58, 0x75, 0x69, + 0x23, 0x25, 0x51, 0x40, 0xc9, 0xfd, 0xd1, 0xe4, 0xf2, 0x4f, + 0xb9, 0x35, 0xe8, 0x5a, 0x7f, 0xfc, 0x16, 0xee, 0x16, 0x61, + 0xf6, 0xef, 0x84, 0xb2, 0x46, 0xbd, 0xcd, 0xbe, 0xb8, 0x1f, + 0xf9, 0xc0, 0x28, 0xb1, 0x57, 0x47, 0xea, 0x45, 0x15, 0xf9, + 0xbd, 0x65, 0xff, 00, 0x5, 0xb1, 0xf0, 0x3c, 0x85, 0x7e, + 0xd7, 0xf0, 0xe3, 0xc4, 0x10, 0xe, 0xe6, 0x1b, 0xc8, 0x24, + 0xc7, 0xe7, 0xb6, 0xba, 0xed, 0x3, 0xfe, 0xb, 0x19, 0xf0, + 0x8b, 0x5c, 0xbd, 0xb6, 0xb3, 0x3e, 0x19, 0xf1, 0x84, 0x17, + 0x57, 0x12, 0x2c, 0x51, 0xc6, 0x2d, 0x20, 0x93, 0x73, 0xb1, + 0xc0, 0x51, 0xb6, 0x6e, 0x72, 0x48, 0xed, 0x48, 0x2e, 0x8f, + 0xbc, 0xe8, 0xa8, 0xad, 0xa6, 0x37, 0x16, 0xd1, 0x4a, 0x63, + 0x78, 0x4b, 0xa0, 0x63, 0x1c, 0x98, 0xdc, 0xb9, 0x19, 0xc1, + 0xc7, 0x71, 0x59, 0x1e, 0x36, 0xf1, 0xae, 0x89, 0xf0, 0xe7, + 0xc2, 0x9a, 0x9f, 0x89, 0x7c, 0x47, 0x7f, 0x1e, 0x97, 0xa2, + 0x69, 0xb0, 0x99, 0xee, 0xee, 0xe5, 0x4, 0xac, 0x48, 0x3b, + 0xe0, 0x2, 0x4f, 0x5e, 0x80, 0x50, 0x33, 0x72, 0x8a, 0xf0, + 0x2b, 0xf, 0xdb, 0xdb, 0xf6, 0x7d, 0xd4, 0x63, 0xf, 0x1f, + 0xc5, 0x6f, 0xf, 0xc6, 0xf, 0x6b, 0x89, 0x9a, 0x23, 0xf9, + 0x32, 0x8a, 0xdc, 0xb1, 0xfd, 0xb1, 0x7e, 0x6, 0xea, 0x3f, + 0xea, 0x3e, 0x2d, 0x78, 0x40, 0xff, 00, 0xbf, 0xac, 0x42, + 0x9f, 0xfa, 0x13, 0xa, 00, 0xf6, 0x1a, 0x2b, 0x82, 0xd2, + 0x7e, 0x3e, 0x7c, 0x33, 0xd7, 0xbf, 0xe4, 0x1d, 0xf1, 0xb, + 0xc2, 0xf7, 0xdf, 0xf5, 0xc3, 0x58, 0xb7, 0x7f, 0xe4, 0xf5, + 0xd1, 0xd9, 0x78, 0xd7, 0xc3, 0xda, 0x91, 0x2, 0xd3, 0x5e, + 0xd3, 0x2e, 0x89, 0xe8, 0x21, 0xbc, 0x8d, 0xf3, 0xf9, 0x35, + 00, 0x6d, 0x51, 0x51, 0xa5, 0xc4, 0x52, 0x7d, 0xc9, 0x51, + 0xbf, 0xdd, 0x60, 0x6a, 0x4a, 00, 0x28, 0xa2, 0x8a, 00, + 0x2a, 0xbd, 0xfe, 0x9f, 0x6d, 0xaa, 0x5a, 0x49, 0x6b, 0x79, + 0x6f, 0x1d, 0xd5, 0xb4, 0x98, 0xdf, 0x14, 0xca, 0x19, 0x5b, + 0x9c, 0xf2, 0xf, 0xbd, 0x58, 0xa2, 0x93, 0x49, 0xab, 0x30, + 0x6a, 0xfa, 0x33, 0x96, 0x9b, 0xe1, 0x77, 0x84, 0xe7, 0x1f, + 0x36, 0x81, 0x62, 0x3f, 0xdc, 0x8b, 0x6f, 0xf2, 0xaa, 0x53, + 0x7c, 0x17, 0xf0, 0x6c, 0xfd, 0x74, 0x54, 0x5f, 0xf7, 0x25, + 0x91, 0x7f, 0x93, 0x57, 0x6d, 0x45, 0x72, 0x4b, 0x5, 0x85, + 0x96, 0xf4, 0xa3, 0xf7, 0x23, 0x27, 0x46, 0x9b, 0xde, 0x2b, + 0xee, 0x3c, 0xf6, 0x4f, 0x80, 0xde, 0xc, 0x7e, 0x9a, 0x74, + 0xa9, 0xfe, 0xed, 0xd4, 0x9f, 0xd5, 0xaa, 0xac, 0x9f, 0xb3, + 0xd7, 0x84, 0x9f, 0xee, 0xa5, 0xe4, 0x7f, 0xee, 0xdc, 0x7f, + 0x88, 0xaf, 0x4c, 0xa2, 0xb0, 0x79, 0x66, 0x9, 0xef, 0x46, + 0x3f, 0x72, 0x23, 0xea, 0xf4, 0x7f, 0x95, 0x18, 0x7e, 0xf, + 0xf0, 0x85, 0x97, 0x82, 0x74, 0x93, 0xa7, 0x58, 0x3c, 0xcf, + 0x6f, 0xe6, 0x34, 0xa3, 0xcf, 0x60, 0xc4, 0x13, 0x8c, 0x8c, + 0x80, 0x38, 0xe2, 0xb7, 0x28, 0xa2, 0xbb, 0xe9, 0xd3, 0x8d, + 0x28, 0xa8, 0x41, 0x59, 0x23, 0x68, 0xc5, 0x45, 0x59, 0x6c, + 0x14, 0x51, 0x45, 0x68, 0x50, 0x57, 0x25, 0xf1, 0x4b, 0xc3, + 0xfa, 0x9f, 0x8a, 0x7c, 0x1f, 0x73, 0xa5, 0xe9, 0x46, 0x21, + 0x3c, 0xee, 0x81, 0xcc, 0xce, 0x50, 0x6c, 0x7, 0x27, 0x9c, + 0x1f, 0x41, 0x5d, 0x6d, 0x15, 0x8d, 0x6a, 0x51, 0xaf, 0x4e, + 0x54, 0xa5, 0xb3, 0x56, 0x22, 0x71, 0x53, 0x8b, 0x8b, 0xea, + 0x7c, 0xb5, 0x2f, 0xc0, 0xf, 0x18, 0x47, 0xd2, 0xd6, 0xda, + 0x4f, 0xf7, 0x2e, 0x17, 0xfa, 0xe2, 0xa9, 0xcb, 0xf0, 0x47, + 0xc6, 0x71, 0xff, 00, 0xcc, 0x1f, 0x7f, 0xfb, 0xb3, 0xc7, + 0xff, 00, 0xc5, 0x57, 0xd6, 0x34, 0x57, 0xcb, 0xcb, 0x86, + 0x30, 0x4f, 0x69, 0x49, 0x7c, 0xd7, 0xf9, 0x1e, 0x7b, 0xcb, + 0xe9, 0x77, 0x67, 0xc8, 0x53, 0x7c, 0x25, 0xf1, 0x7c, 0x7, + 0xe6, 0xd0, 0x6e, 0x8f, 0xfb, 0x9b, 0x5b, 0xf9, 0x1a, 0xa3, + 0x3f, 0xc3, 0xef, 0x13, 0x5b, 0xff, 00, 0xac, 0xd0, 0x75, + 0x1, 0xf4, 0xb7, 0x63, 0xfc, 0x85, 0x7d, 0x97, 0x45, 0x61, + 0x2e, 0x16, 0xc3, 0x7d, 0x9a, 0x92, 0xfc, 0x3f, 0xc8, 0x87, + 0x97, 0x43, 0xa4, 0x99, 0xe7, 0xdf, 0x3, 0xbc, 0x37, 0x2f, + 0x87, 0x7c, 0xb, 0xf, 0xda, 0x61, 0x78, 0x2e, 0xee, 0xe5, + 0x79, 0xe4, 0x49, 0x14, 0xab, 0x2f, 0x3b, 0x54, 0x10, 0x7a, + 0x70, 0xa0, 0xfe, 0x35, 0xe8, 0x34, 0x51, 0x5f, 0x59, 0x86, + 0xa1, 0x1c, 0x35, 0x18, 0xd1, 0x8e, 0xd1, 0x56, 0x3d, 0x2a, + 0x70, 0x54, 0xe0, 0xa0, 0xba, 0x5, 0x14, 0x51, 0x5d, 0x26, + 0x81, 0x45, 0x14, 0x50, 0x1, 0x45, 0x14, 0x50, 0x6, 0x57, + 0x88, 0xfc, 0x33, 0xa6, 0xf8, 0xb3, 0x4d, 0x7b, 0x1d, 0x4e, + 0xd9, 0x6e, 0x20, 0x6e, 0x46, 0x78, 0x64, 0x3e, 0xaa, 0x7a, + 0x83, 0x5f, 0x3a, 0xf8, 0xef, 0xe0, 0x66, 0xb1, 0xe1, 0x97, + 0x96, 0xe7, 0x4d, 0x56, 0xd5, 0xb4, 0xd1, 0xc8, 0x31, 0x8c, + 0xcc, 0x83, 0xfd, 0xa5, 0x1d, 0x7e, 0xa3, 0xf2, 0x15, 0xf4, + 0xfd, 0x15, 0xe3, 0xe3, 0xf2, 0xac, 0x3e, 0x60, 0xbf, 0x78, + 0xad, 0x2e, 0xeb, 0x7f, 0xf8, 0x27, 0x2d, 0x6c, 0x34, 0x2b, + 0xfc, 0x5b, 0xf7, 0x3e, 0x15, 0x20, 0xa9, 0x20, 0x8c, 0x11, + 0xc1, 0x7, 0xb5, 0x25, 0x7d, 0x89, 0xe2, 0x7f, 0x86, 0xde, + 0x1e, 0xf1, 0x70, 0x63, 0x7f, 0xa7, 0x47, 0xe7, 0x9f, 0xf9, + 0x78, 0x87, 0xe4, 0x90, 0x7e, 0x23, 0xaf, 0xe3, 0x9a, 0xf3, + 0x2d, 0x6b, 0xf6, 0x66, 0x53, 0xb9, 0xb4, 0x9d, 0x64, 0x8f, + 0x48, 0xaf, 0x23, 0xcf, 0xfe, 0x3c, 0xbf, 0xe1, 0x5f, 0x5, + 0x89, 0xe1, 0xbc, 0x65, 0x17, 0x7a, 0x56, 0x9a, 0xfb, 0x9f, + 0xdc, 0xff, 00, 0xcc, 0xf1, 0xaa, 0x60, 0x2a, 0xc7, 0xe1, + 0xd4, 0xf0, 0x8a, 0x2b, 0xd0, 0x35, 0x3f, 0x81, 0x5e, 0x30, + 0xd3, 0xdc, 0x84, 0xb0, 0x8e, 0xf5, 0x7, 0xf1, 0xdb, 0x4c, + 0xa7, 0xf4, 0x62, 0xf, 0xe9, 0x58, 0x57, 0x3f, 0xe, 0x3c, + 0x53, 0x68, 0x71, 0x26, 0x81, 0x7f, 0xff, 00, 00, 0x81, + 0x9c, 0x7e, 0x99, 0xaf, 0xa, 0xa6, 0x7, 0x15, 0x49, 0xda, + 0x74, 0xa4, 0xbe, 0x4c, 0xe2, 0x74, 0x6a, 0x47, 0x78, 0xb3, + 0x9c, 0xa2, 0xb4, 0xe4, 0xf0, 0xc6, 0xb3, 0x11, 0xc3, 0xe9, + 0x37, 0xca, 0x7d, 0xd, 0xb3, 0xff, 00, 0x85, 0x35, 0x7c, + 0x39, 0xab, 0x31, 0xc0, 0xd2, 0xaf, 0x4f, 0xd2, 0xd9, 0xff, + 00, 0xc2, 0xb9, 0xbd, 0x95, 0x4f, 0xe5, 0x7f, 0x71, 0x1c, + 0xb2, 0xec, 0x67, 0x51, 0x5b, 0xf6, 0xfe, 00, 0xf1, 0x2d, + 0xd1, 0x1e, 0x56, 0x83, 0xa8, 0xb6, 0x7a, 0x13, 0x6c, 0xe0, + 0x7e, 0x64, 0x56, 0xe6, 0x9d, 0xf0, 0x47, 0xc6, 0x3a, 0x83, + 0xa8, 0x3a, 0x5f, 0xd9, 0x50, 0xff, 00, 0x1d, 0xc4, 0xa8, + 0xa0, 0x7e, 0x19, 0x27, 0xf4, 0xae, 0x88, 0x60, 0xb1, 0x35, + 0x3e, 0xa, 0x52, 0x7f, 0x26, 0x5a, 0xa5, 0x52, 0x5b, 0x45, + 0x9c, 0x25, 0x15, 0xee, 0x3a, 0x2f, 0xec, 0xcf, 0x2b, 0x6d, + 0x6d, 0x5b, 0x58, 0x54, 0xf5, 0x8a, 0xce, 0x3c, 0x9f, 0xfb, + 0xe9, 0xbf, 0xc2, 0xbd, 0x2f, 0xc3, 0x1f, 0xa, 0x7c, 0x35, + 0xe1, 0x4d, 0xaf, 0x6b, 0xa7, 0xac, 0xf7, 0x2b, 0xff, 00, + 0x2f, 0x17, 0x5f, 0xbc, 0x7f, 0xc3, 0x3c, 0xf, 0xc0, 0xa, + 0xf7, 0x30, 0xdc, 0x39, 0x8d, 0xac, 0xef, 0x51, 0x28, 0x2f, + 0x3d, 0x5f, 0xdc, 0xbf, 0xe0, 0x1d, 0x94, 0xf0, 0x35, 0x67, + 0xf1, 0x68, 0x7c, 0xfd, 0xe0, 0xbf, 0x83, 0x9a, 0xff, 00, + 0x8c, 0xc, 0x73, 0x18, 0x7f, 0xb3, 0xb4, 0xf6, 0x23, 0x37, + 0x37, 0x20, 0x82, 0x47, 0xaa, 0xaf, 0x56, 0xfd, 0x7, 0xbd, + 0x7d, 0xf, 0xe0, 0x9f, 0x87, 0x3a, 0x37, 0x81, 0x6d, 0xb6, + 0xd8, 0xc1, 0xe6, 0x5d, 0x32, 0xe2, 0x5b, 0xb9, 0x79, 0x91, + 0xff, 00, 0xc0, 0x7b, 0xa, 0xea, 0x68, 0xaf, 0xba, 0xc0, + 0x64, 0xd8, 0x6c, 0x7, 0xbd, 0x15, 0xcd, 0x2e, 0xef, 0xf4, + 0xec, 0x7b, 0x14, 0x30, 0xb4, 0xe8, 0xea, 0xb5, 0x7d, 0xc2, + 0x8a, 0x28, 0xaf, 0x74, 0xec, 0xa, 0xe5, 0x7e, 0x28, 0x6b, + 0xe3, 0xc3, 0x7e, 0x5, 0xd5, 0xae, 0xc3, 0x6d, 0x95, 0xa2, + 0x30, 0xc4, 0x7b, 0xef, 0x7f, 0x94, 0x7e, 0x59, 0xcf, 0xe1, + 0x5d, 0x55, 0x78, 0xc7, 0xed, 0x29, 0x71, 0x76, 0xfa, 0x46, + 0x95, 0x69, 0xd, 0xbc, 0xcf, 0x6d, 0xe6, 0xb4, 0xf3, 0x4a, + 0x88, 0x4a, 0x29, 0x3, 0xa, 0x9, 0xe9, 0xfc, 0x4d, 0xf9, + 0x57, 0x99, 0x99, 0xd7, 0x78, 0x7c, 0x1d, 0x4a, 0x91, 0xde, + 0xda, 0x7c, 0xf4, 0x39, 0xf1, 0x13, 0x70, 0xa5, 0x29, 0x23, + 0xe7, 0xba, 0x28, 0xa2, 0xbf, 0x12, 0x3e, 0x48, 0x28, 0xa2, + 0x8a, 00, 0x28, 0xa2, 0x8a, 00, 0x28, 0xa2, 0x8a, 00, + 0x28, 0xa2, 0x8a, 00, 0x28, 0xa2, 0xbb, 0x3f, 0x5, 0x7c, + 0x27, 0xd7, 0xbc, 0x69, 0x2c, 0x4f, 0x15, 0xbb, 0x59, 0x69, + 0xed, 0xc9, 0xbd, 0xb8, 0x5c, 0x2e, 0x3f, 0xd9, 0x1d, 0x5b, + 0xf0, 0xe3, 0xde, 0xb7, 0xa3, 0x42, 0xae, 0x22, 0x6a, 0x9d, + 0x18, 0xb6, 0xfc, 0x8b, 0x84, 0x25, 0x37, 0x68, 0xab, 0xb3, + 0x9c, 0xd0, 0x34, 0x1b, 0xdf, 0x13, 0x6a, 0xd6, 0xfa, 0x76, + 0x9f, 0x17, 0x9d, 0x73, 0x33, 0x60, 0xe, 0xca, 0x3b, 0xb1, + 0x3d, 0x80, 0xf5, 0xaf, 0xae, 0xbc, 0xb, 0xe0, 0xeb, 0x5f, + 0x3, 0xf8, 0x7a, 0xd, 0x3a, 0xdc, 0x6, 0x90, 0xd, 0xf3, + 0xcc, 0x6, 0xc, 0xb2, 0x1e, 0xa7, 0xfa, 0xf, 0x6a, 0x87, + 0xc0, 0xdf, 0xf, 0xb4, 0xbf, 0x1, 0x58, 0x18, 0x2c, 0x50, + 0xc9, 0x71, 0x26, 0x3c, 0xeb, 0xa9, 00, 0xdf, 0x21, 0xfe, + 0x83, 0xd8, 0x57, 0x4f, 0x5f, 0xa9, 0x64, 0xd9, 0x3a, 0xcb, + 0xe3, 0xed, 0x6a, 0xeb, 0x51, 0xfe, 0xb, 0xb7, 0xf9, 0x9f, + 0x43, 0x85, 0xc2, 0xfb, 0x5, 0xcd, 0x2f, 0x88, 0x28, 0xa2, + 0x8a, 0xfa, 0x73, 0xd1, 0xa, 0x28, 0xa2, 0x80, 0x30, 0x7c, + 0x73, 0x37, 0x91, 0xe1, 0x8b, 0xd6, 0xe9, 0xf2, 0xe2, 0xbe, + 0x8, 0xf1, 0xc4, 0xbe, 0x66, 0xbd, 0x72, 0x73, 0xfc, 0x46, + 0xbe, 0xe8, 0xf8, 0x9f, 0x37, 0x93, 0xe1, 0x2b, 0xa3, 0x9a, + 0xf8, 0x2f, 0xc5, 0xd, 0xbf, 0x55, 0xba, 0x6c, 0xff, 00, + 0x11, 0xaf, 0x84, 0xe2, 0x19, 0x7e, 0xfa, 0x9c, 0x4f, 0x88, + 0xe2, 0x49, 0x7b, 0x91, 0x47, 0x8f, 0x7c, 0x59, 0x9f, 0xcb, + 0xd2, 0x64, 0xe7, 0xb1, 0xfe, 0x55, 0xf7, 0x67, 0xfc, 0x13, + 0xa2, 0xc9, 0xad, 0x3f, 0x64, 0xaf, 0x8, 0xbb, 0xc, 0x1b, + 0x89, 0xaf, 0x67, 0xfc, 0xd, 0xd4, 0xa3, 0xfa, 0x57, 0xc0, + 0x5f, 0x19, 0xa6, 0xf2, 0xf4, 0xa9, 0x79, 0xe3, 0x69, 0xaf, + 0xd2, 0x7f, 0xd8, 0xaf, 0x4a, 0x1a, 0x3f, 0xec, 0xaf, 0xf0, + 0xda, 00, 0x41, 0xdf, 0xa5, 0x25, 0xc1, 0xc7, 0xac, 0x8c, + 0xd2, 0x7f, 0xec, 0xd5, 0xed, 0xe5, 0xa, 0xd4, 0x91, 0xe6, + 0xf0, 0x74, 0x7d, 0xda, 0xf3, 0xf3, 0x3d, 0xb2, 0x8a, 0x28, + 0xaf, 0xa0, 0x3f, 0x49, 0x39, 0x5f, 0x8a, 0x1e, 0x30, 0x4f, + 0x2, 0x78, 0x13, 0x56, 0xd6, 0x18, 0xfe, 0xf2, 0x18, 0xb6, + 0xc2, 0x3d, 0x65, 0x6f, 0x95, 0x7, 0xe6, 0x45, 0x7e, 0x7e, + 0xa7, 0x99, 0x77, 0x71, 0x96, 0x26, 0x49, 0xa5, 0x6c, 0xb3, + 0x1e, 0x4b, 0x31, 0x3c, 0x9f, 0xce, 0xbe, 0x93, 0xfd, 0xaf, + 0xfc, 0x64, 0xf, 0xf6, 0x4f, 0x85, 0xa1, 0x3c, 0xff, 00, + 0xc7, 0xf5, 0xc1, 0xf6, 0xe5, 0x50, 0x7f, 0xe8, 0x47, 0xf0, + 0x15, 0xe3, 0xbf, 0x8, 0x3c, 0x2a, 0xde, 0x2d, 0xf1, 0xd6, + 0x9b, 0x69, 0xb4, 0xb4, 0x42, 0x40, 0xf2, 0x7b, 0x28, 0xe6, + 0xbf, 0x3e, 0xce, 0xab, 0x4b, 0x13, 0x8b, 0x8e, 0x1e, 0x1d, + 0x34, 0xf9, 0xb3, 0xf3, 0xbc, 0xe2, 0xa3, 0xc6, 0xe3, 0xe3, + 0x86, 0x86, 0xd1, 0xd3, 0xe6, 0xf7, 0xfd, 0xf, 0xae, 0xfe, + 0x7, 0x78, 0x51, 0x7c, 0x2b, 0xf0, 0xff, 00, 0x4f, 0x8c, + 0xa8, 0x59, 0xe7, 0x5f, 0x36, 0x43, 0x8e, 0xe6, 0xbd, 0x2, + 0xa3, 0xb7, 0x81, 0x2d, 0xa0, 0x8e, 0x14, 0x1b, 0x51, 0x14, + 0x28, 0x3, 0xd0, 0x54, 0x95, 0xf7, 0x54, 0x29, 0x2a, 0x14, + 0xa3, 0x4a, 0x3b, 0x25, 0x63, 0xef, 0xe9, 0x53, 0x54, 0xa1, + 0x18, 0x47, 0x64, 0x14, 0x51, 0x45, 0x6e, 0x6a, 0x7e, 0x70, + 0xff, 00, 0xc1, 0x43, 0xbf, 0xe0, 0x9c, 0x3a, 0xf7, 0xc6, + 0x5f, 0x19, 0x5d, 0x7c, 0x4c, 0xf8, 0x6b, 0xf6, 0x7b, 0x8d, + 0x7a, 0xea, 0x24, 0x1a, 0xae, 0x87, 0x33, 0x88, 0x9a, 0xe9, + 0xd1, 0x42, 0xac, 0xb1, 0x39, 0xf9, 0x77, 0x95, 0x55, 0x52, + 0xad, 0x8c, 0xed, 0x4, 0x1e, 0xb5, 0xf9, 0x9d, 0xe2, 0x4f, + 0xd9, 0xa7, 0xe2, 0xcf, 0x84, 0x2e, 0xe4, 0xb6, 0xd5, 0xfe, + 0x1b, 0x78, 0xaa, 0xce, 0x54, 0xfb, 0xc4, 0xe9, 0x13, 0xba, + 0x7e, 0xe, 0xaa, 0x54, 0xfe, 0x6, 0xbf, 0xa4, 0xfa, 0xe7, + 0xbe, 0x21, 0x78, 0xca, 0xdb, 0xe1, 0xe7, 0x81, 0xb5, 0xef, + 0x13, 0x5e, 0x47, 0x24, 0xd6, 0xfa, 0x55, 0x9c, 0xb7, 0x6d, + 0x14, 0x2a, 0x59, 0xe4, 0xda, 0xa4, 0x84, 0x50, 0x39, 0x2c, + 0xc7, 00, 0x1, 0xdc, 0xd3, 0xb9, 0x2d, 0x5c, 0xfe, 0x63, + 0xef, 0xac, 0x6e, 0x74, 0xcb, 0xb9, 0x6d, 0x6f, 0x2d, 0xe5, + 0xb4, 0xba, 0x85, 0xb6, 0x49, 0x4, 0xe8, 0x51, 0xd1, 0xbd, + 0xa, 0x9e, 0x41, 0xfa, 0xd5, 0x7a, 0xeb, 0x3e, 0x21, 0x5c, + 0x78, 0x93, 0xc5, 0xbe, 0x32, 0xd7, 0x7c, 0x49, 0xae, 0x69, + 0xb7, 0xb0, 0xea, 0x1a, 0xb5, 0xf4, 0xd7, 0xf7, 0x6, 0x68, + 0x1d, 0x70, 0xf2, 0x39, 0x72, 0x39, 0x1d, 0x1, 0x38, 0xaf, + 0xd9, 0xef, 0xf8, 0x27, 0x3f, 0xec, 0xbd, 0xe1, 0xaf, 0x8, + 0x7e, 0xcb, 0x5e, 0x1e, 0xbd, 0xf1, 0x2f, 0x86, 0xf4, 0xcd, + 0x5b, 0x58, 0xf1, 0x29, 0x3a, 0xcc, 0xe7, 0x52, 0xb1, 0x49, + 0x9a, 0x38, 0xe4, 00, 0x42, 0x9f, 0x38, 0x38, 0xc4, 0x6a, + 0xa7, 0x1e, 0xac, 0x69, 0xdc, 0x9b, 0x5c, 0xfc, 0x36, 0xa2, + 0xbf, 0xa4, 0x3d, 0x67, 0xf6, 0x53, 0xf8, 0x37, 0xe2, 0x2, + 0x7f, 0xb4, 0x3e, 0x17, 0xf8, 0x52, 0xe7, 0x3e, 0xba, 0x4c, + 0x23, 0xf9, 0x28, 0xae, 0x53, 0x54, 0xfd, 0x81, 0x7f, 0x67, + 0xbd, 0x5c, 0x62, 0x6f, 0x85, 0x5a, 0xc, 0x5f, 0xf5, 0xeb, + 0x1b, 0xc1, 0xff, 00, 0xa0, 0x30, 0xa5, 0x71, 0xf2, 0x9f, + 0xcf, 0x3d, 0x7d, 0x3f, 0xff, 00, 0x4, 0xe1, 0xf8, 0x2a, + 0x7e, 0x34, 0x7e, 0xd4, 0xfe, 0x18, 0x8e, 0xe2, 0x3, 0x2e, + 0x8f, 0xe1, 0xf6, 0xfe, 0xdc, 0xbe, 0xc8, 0x3b, 0x71, 0x9, + 0x6, 0x25, 0x27, 0xde, 0x53, 0x1f, 0xe0, 0xd, 0x7e, 0xa9, + 0x6a, 0x5f, 0xf0, 0x4c, 0x4f, 0xd9, 0xc3, 0x51, 0x18, 0xff, + 00, 0x84, 00, 0xda, 0xfb, 0xdb, 0x6a, 0x97, 0x69, 0xff, + 00, 0xb5, 0x6b, 0xd0, 0x3e, 00, 0xfe, 0xc8, 0x5f, 0xc, + 0xbf, 0x66, 0x6d, 0x43, 0x59, 0xbd, 0xf0, 0xe, 0x8d, 0x71, + 0xa6, 0xdc, 0xea, 0xd1, 0xc7, 0xd, 0xd3, 0xdc, 0x5e, 0xcb, + 0x72, 0x4a, 0x21, 0x62, 0xa1, 0x7c, 0xc2, 0x76, 0x8c, 0xb1, + 0xce, 0x3a, 0xf1, 0xe9, 0x45, 0xc3, 0x94, 0xf6, 0x7a, 0xfc, + 0xf8, 0xff, 00, 0x82, 0xc6, 0xfc, 0x66, 0x3e, 0x11, 0xf8, + 0x31, 0xa1, 0x7c, 0x3f, 0xb3, 0x98, 0xa5, 0xef, 0x8a, 0x6e, + 0xfc, 0xeb, 0x90, 0xa7, 0x9f, 0xb2, 0x5b, 0x95, 0x62, 0xf, + 0xd6, 0x46, 0x8f, 0xfe, 0xf9, 0x35, 0xfa, 0xf, 0x5f, 0x23, + 0xfe, 0xd6, 0x9f, 0xf0, 0x4f, 0x2d, 0x1b, 0xf6, 0xb2, 0xf1, + 0xd5, 0xaf, 0x8a, 0x35, 0x7f, 0x1c, 0x6b, 0x1a, 0x34, 0xf6, + 0x96, 0x6b, 0x65, 0x6d, 0x65, 0x6f, 0x6f, 0x14, 0x90, 0x44, + 0x80, 0x96, 0x24, 0x3, 0x83, 0x96, 0x66, 0x24, 0xf3, 0xd8, + 0x7a, 0x52, 0x29, 0x9f, 0x83, 0xf4, 0x57, 0xea, 0x9e, 0xa5, + 0xff, 00, 0x4, 0x45, 0xb5, 0x20, 0xfd, 0x83, 0xe2, 0xc4, + 0xca, 0x7b, 0xb, 0x9d, 0x10, 0x1f, 0xd5, 0x66, 0x15, 0xcf, + 0x5d, 0xff, 00, 0xc1, 0x11, 0xbc, 0x42, 0xaa, 0x4d, 0xaf, + 0xc5, 0x6d, 0x32, 0x46, 0xec, 0x26, 0xd1, 0xe4, 0x41, 0xf9, + 0x89, 0x4f, 0xf2, 0xaa, 0xb9, 0x16, 0x67, 0xe6, 0x66, 0x7, + 0xa5, 0x49, 0x14, 0xf2, 0x42, 0x7f, 0x77, 0x23, 0xc7, 0xfe, + 0xeb, 0x11, 0x5f, 0xa2, 0x1a, 0x87, 0xfc, 0x11, 0x57, 0xe2, + 0x44, 0x8, 0x4d, 0x9f, 0x8f, 0x3c, 0x31, 0x74, 0x7b, 0x2c, + 0x91, 0xdc, 0x47, 0xff, 00, 0xb2, 0x1a, 0xe3, 0xf5, 0x4f, + 0xf8, 0x23, 0xd7, 0xc7, 0x5b, 0x32, 0xdf, 0x65, 0xb9, 0xf0, + 0xb5, 0xfa, 0x8e, 0x9e, 0x5e, 0xa4, 0xe8, 0x4f, 0xfd, 0xf5, + 0x10, 0xa2, 0xe1, 0x66, 0x7c, 0x69, 0xa6, 0xf8, 0xcf, 0xc4, + 0x1a, 0x3b, 0x87, 0xb0, 0xd7, 0x75, 0x3b, 0x17, 0x1d, 0x1a, + 0xda, 0xf2, 0x48, 0xcf, 0xe8, 0xc2, 0xba, 0x9d, 0x3f, 0xf6, + 0x87, 0xf8, 0xa7, 0xa5, 0x38, 0x6b, 0x4f, 0x89, 0x1e, 0x2c, + 0x84, 0x8e, 0x9b, 0x75, 0xab, 0x9c, 0xf, 0xc3, 0x7d, 0x7b, + 0xce, 0xa5, 0xff, 00, 0x4, 0xab, 0xfd, 0xa2, 0x74, 0xf0, + 0x4a, 0x78, 0x5b, 0x4f, 0xbd, 0x3, 0xfe, 0x7d, 0x75, 0x68, + 0xe, 0x7f, 0xef, 0xa6, 0x15, 0xc9, 0xea, 0x7f, 0xf0, 0x4e, + 0xbf, 0xda, 0x27, 0x4a, 0x4, 0xbf, 0xc3, 0x2d, 0x46, 0x75, + 0x1d, 0xed, 0xae, 0x2d, 0xe5, 0xfd, 0x16, 0x4c, 0xd0, 0x16, + 0x67, 0x33, 0x61, 0xfb, 0x69, 0x7c, 0x76, 0xd3, 0x48, 0xf2, + 0x3e, 0x2b, 0xf8, 0xa7, 0x8e, 0x82, 0x4d, 0x41, 0xe4, 0x1f, + 0xf8, 0xf6, 0x6b, 0xa1, 0xb4, 0xff, 00, 0x82, 0x86, 0xfe, + 0xd1, 0x56, 0x61, 0x44, 0x7f, 0x14, 0xb5, 0x56, 0x3, 0xfe, + 0x7a, 0xc1, 0x6f, 0x27, 0xfe, 0x85, 0x19, 0xae, 0x67, 0x53, + 0xfd, 0x8d, 0xfe, 0x39, 0x69, 0x19, 0xfb, 0x4f, 0xc2, 0x9f, + 0x15, 0xe0, 0x75, 0x31, 0x69, 0x92, 0x4b, 0xff, 00, 0xa0, + 0x3, 0x5c, 0xdd, 0xd7, 0xec, 0xf7, 0xf1, 0x4a, 0xc7, 0x3f, + 0x68, 0xf8, 0x6f, 0xe2, 0xd8, 0x71, 0xd7, 0x7e, 0x87, 0x72, + 0x3f, 0xf6, 0x4a, 0x3, 0x53, 0xda, 0x2c, 0xbf, 0xe0, 0xa7, + 0x9f, 0xb4, 0x7d, 0x96, 0x3f, 0xe2, 0xbf, 0x17, 00, 0x76, + 0x9f, 0x4a, 0xb4, 0x6c, 0xff, 00, 0xe4, 0x2a, 0xea, 0x34, + 0xff, 00, 0xf8, 0x2b, 0x87, 0xed, 0x5, 0x64, 0x81, 0x65, + 0xd4, 0x3c, 0x3f, 0x7d, 0x8e, 0xf7, 0x1a, 0x4a, 0x82, 0x7f, + 0xef, 0x96, 0x5a, 0xf9, 0x4e, 0xf7, 0xe1, 0xaf, 0x8b, 0xf4, + 0xd0, 0x4d, 0xdf, 0x85, 0x75, 0xbb, 0x50, 0x3a, 0xf9, 0xfa, + 0x74, 0xc9, 0x8f, 0xcd, 0x6b, 0xe, 0xeb, 0x4f, 0xba, 0xb2, + 0x38, 0xb8, 0xb6, 0x9a, 0x3, 0xe9, 0x2c, 0x65, 0x7f, 0x9d, + 0x1, 0x76, 0x7d, 0xe7, 0xa5, 0x7f, 0xc1, 0x66, 0x3e, 0x30, + 0xda, 0x15, 0xfb, 0x6f, 0x87, 0x7c, 0x2b, 0x7e, 0x7, 0x5f, + 0xf4, 0x79, 0xa2, 0xcf, 0xe5, 0x25, 0x75, 0x76, 0x1f, 0xf0, + 0x5b, 0x3f, 0x18, 0xc5, 0x8f, 0xb6, 0xfc, 0x33, 0xd0, 0xee, + 0x3d, 0x7c, 0x8d, 0x42, 0x68, 0xbf, 0x9a, 0xb5, 0x7e, 0x6c, + 0xe4, 0x52, 0xd1, 0x60, 0xbb, 0x3f, 0x53, 0x74, 0xef, 0xf8, + 0x2d, 0xd0, 0x38, 0xfb, 0x7f, 0xc2, 0x82, 0xbe, 0xbf, 0x66, + 0xd6, 0xb3, 0xfc, 0xe1, 0x15, 0xd2, 0xd9, 0xff, 00, 0xc1, + 0x6c, 0xfc, 0x1a, 0xe0, 0x7d, 0xaf, 0xe1, 0xae, 0xbb, 0x11, + 0xef, 0xe4, 0xdf, 0x42, 0xff, 00, 0xcc, 0x2d, 0x7e, 0x46, + 0xd1, 0x45, 0x82, 0xec, 0xfd, 0x8f, 0xb1, 0xff, 00, 0x82, + 0xd2, 0xfc, 0x29, 0x9b, 0x2, 0xe7, 0xc1, 0x9e, 0x2e, 0xb6, + 0xf5, 0x2b, 0x1d, 0xb3, 0x8f, 0xfd, 0x1c, 0x2b, 0xa4, 0xd3, + 0xbf, 0xe0, 0xb0, 0xff, 00, 0x2, 0xef, 0x31, 0xf6, 0x9b, + 0x5f, 0x14, 0xd8, 0x13, 0xff, 00, 0x3d, 0x74, 0xd4, 0x70, + 0x3f, 0xef, 0x89, 0xd, 0x7e, 0x26, 0x51, 0x45, 0x87, 0xcc, + 0xcf, 0xdd, 0xdd, 0x3f, 0xfe, 0xa, 0xad, 0xfb, 0x3a, 0x5f, + 0x85, 0xdd, 0xe2, 0xbb, 0xfb, 0x46, 0x3f, 0xc3, 0x71, 0xa3, + 0xdc, 0x8c, 0x7e, 0x21, 0x8, 0xae, 0xb7, 0x4b, 0xff, 00, + 0x82, 0x89, 0x7e, 0xce, 0xfa, 0xaa, 0x6, 0x4f, 0x89, 0xba, + 0x6d, 0xb9, 0x3f, 0xc3, 0x75, 0xc, 0xd1, 0x1f, 0xd5, 0x2b, + 0xf9, 0xf5, 0xa2, 0x8b, 0x7, 0x31, 0xfd, 0x18, 0x69, 0xdf, + 0xb6, 0x8f, 0xc0, 0x8d, 0x51, 0x41, 0x83, 0xe2, 0xcf, 0x84, + 0xf9, 0xe8, 0x25, 0xd4, 0xe3, 0x88, 0xfe, 0x4e, 0x41, 0xae, + 0xa3, 0x4a, 0xfd, 0xa0, 0xbe, 0x18, 0x6b, 0x60, 0x7d, 0x83, + 0xe2, 0x1f, 0x85, 0xee, 0xf3, 0xff, 00, 0x3c, 0xb5, 0x7b, + 0x73, 0xff, 00, 0xb3, 0xd7, 0xf3, 0x4f, 0x45, 0x2b, 0x7, + 0x31, 0xfd, 0x3c, 0xd9, 0xf8, 0xff, 00, 0xc2, 0xfa, 0x81, + 0xc5, 0xaf, 0x89, 0x34, 0x8b, 0x92, 0x7b, 0x43, 0x7d, 0x13, + 0xff, 00, 0x26, 0xad, 0x58, 0x75, 0x5b, 0x2b, 0x83, 0x88, + 0xaf, 0x2d, 0xe4, 0x3e, 0x89, 0x2a, 0x9f, 0xeb, 0x5f, 0xcb, + 0x86, 0x7, 0xa5, 0x5a, 0xb4, 0xd5, 0x2f, 0x34, 0xf6, 0x6, + 0xd6, 0xee, 0x7b, 0x62, 0x3a, 0x18, 0x65, 0x64, 0xfe, 0x46, + 0x8b, 0xf, 0x98, 0xfe, 0xa3, 0x83, 0x3, 0xd0, 0x83, 0x4b, + 0x5f, 0xcc, 0x86, 0x9f, 0xf1, 0x5b, 0xc6, 0xda, 0x49, 0x6, + 0xc7, 0xc6, 0x3a, 0xfd, 0x91, 0x1d, 0xd, 0xbe, 0xa9, 0x3c, + 0x7f, 0xc9, 0xeb, 0xa8, 0xd2, 0xff, 00, 0x6a, 0x6f, 0x8c, + 0x5a, 0x2c, 0x8a, 0xf6, 0x9f, 0x14, 0x3c, 0x5a, 0x85, 0x7a, + 0x6f, 0xd6, 0x27, 0x90, 0x7e, 0x4c, 0xc4, 0x51, 0x60, 0xe6, + 0x3f, 0xa4, 0x7a, 0x2b, 0xf9, 0xe6, 0xb3, 0xfd, 0xbf, 0x3f, + 0x68, 0x4b, 0x12, 0xbe, 0x5f, 0xc5, 0x5d, 0x71, 0xb6, 0xf4, + 0x12, 0x98, 0xe4, 0x1f, 0xf8, 0xf2, 0x1a, 0xe8, 0xec, 0x7f, + 0xe0, 0xa6, 0x9f, 0xb4, 0x7d, 0x96, 0xd1, 0xff, 00, 0xb, + 0xd, 0xee, 0x15, 0x7b, 0x4f, 0xa6, 0x5a, 0x36, 0x7e, 0xa7, + 0xca, 0xcd, 0x16, 0xe, 0x64, 0x7e, 0xfb, 0x51, 0x5f, 0x86, + 0x76, 0x3f, 0xf0, 0x56, 0xcf, 0xda, 0x12, 0xce, 0x35, 0x57, + 0xd5, 0x34, 0x2b, 0xbc, 0x7f, 0x14, 0xfa, 0x42, 0x64, 0xff, + 00, 0xdf, 0x24, 0x56, 0xdd, 0x97, 0xfc, 0x16, 0x33, 0xe3, + 0xad, 0xb6, 0x4, 0xda, 0x7f, 0x84, 0x2e, 0xfd, 0xe4, 0xd3, + 0x66, 0x53, 0xff, 00, 0x8e, 0xce, 0x28, 0xb0, 0x5d, 0x1f, + 0xb6, 0x34, 0x57, 0xe3, 0xb6, 0x9d, 0xff, 00, 0x5, 0xa8, + 0xf8, 0x9b, 0x2, 0xa8, 0xbd, 0xf0, 0x3f, 0x85, 0xee, 0xdb, + 0xb9, 0x8d, 0xae, 0x22, 0xcf, 0xfe, 0x3e, 0x6b, 0xa5, 0xd3, + 0xff, 00, 0xe0, 0xb7, 0x1a, 0xfc, 0x78, 0xfb, 0x77, 0xc2, + 0xbd, 0x36, 0x7f, 0xfa, 0xf7, 0xd5, 0xe4, 0x8f, 0xf9, 0xc4, + 0xd4, 0x58, 0x77, 0x47, 0xeb, 0x25, 0x15, 0xf9, 0x8b, 0xa5, + 0x7f, 0xc1, 0x6e, 0x34, 0x77, 0x51, 0xfd, 0xa5, 0xf0, 0xae, + 0xfa, 0x16, 0xef, 0xf6, 0x5d, 0x5d, 0x24, 0x1f, 0xf8, 0xf4, + 0x6b, 0x5d, 0xd, 0xaf, 0xfc, 0x16, 0xbf, 0xe1, 0xe3, 0x91, + 0xf6, 0x9f, 0x87, 0xbe, 0x27, 0x88, 0x7a, 0xc5, 0x35, 0xb3, + 0xff, 00, 0x37, 0x5a, 0x2, 0xe8, 0xfd, 0x19, 0xa2, 0xbe, + 0x1, 0xd3, 0x7f, 0xe0, 0xb3, 0xbf, 0x7, 0xae, 0xdc, 0xb, + 0xaf, 0xc, 0x78, 0xc2, 0xc4, 0x7f, 0x79, 0xed, 0xad, 0x9c, + 0x7f, 0xe3, 0xb3, 0x1a, 0xeb, 0x74, 0xef, 0xf8, 0x2b, 0x87, + 0xec, 0xfb, 0x79, 0x8f, 0x3b, 0x50, 0xd7, 0xac, 0x49, 0xff, + 00, 0x9e, 0xfa, 0x4b, 0x9c, 0x7f, 0xdf, 0x24, 0xd2, 0xb, + 0xa3, 0xed, 0x1a, 0x2b, 0xe5, 0x5d, 0x33, 0xfe, 0xa, 0x7d, + 0xfb, 0x39, 0xea, 0x78, 0x1f, 0xf0, 0x9d, 0x3d, 0xa1, 0x3d, + 0xae, 0xb4, 0xcb, 0x94, 0xfd, 0x7c, 0xbc, 0x57, 0x57, 0xa6, + 0xfe, 0xdf, 0x1f, 0xb3, 0xee, 0xa8, 0x7, 0x95, 0xf1, 0x4f, + 0x42, 0x8c, 0x9e, 0xd7, 0x12, 0x3c, 0x47, 0xff, 00, 0x1e, + 0x51, 0x40, 0xcf, 0x7f, 0xa2, 0xbc, 0x9b, 0x4e, 0xfd, 0xad, + 0x7e, 0xb, 0x6a, 0xc4, 0xb, 0x5f, 0x8a, 0x7e, 0x13, 0x90, + 0x9e, 0xcd, 0xab, 0xc2, 0xa7, 0xf5, 0x61, 0x5d, 0x4d, 0x87, + 0xc6, 0x4f, 00, 0xea, 0xb8, 0xfb, 0x17, 0x8d, 0xbc, 0x3b, + 0x77, 0x9e, 0x9e, 0x4e, 0xab, 0x3, 0x67, 0xf2, 0x7a, 00, + 0xec, 0x28, 0xac, 0x9b, 0x7f, 0x17, 0x68, 0x57, 0x78, 0xf2, + 0x35, 0xad, 0x3a, 0x6c, 0xff, 00, 0xcf, 0x3b, 0xa8, 0xdb, + 0xf9, 0x1a, 0xd0, 0x8a, 0xf2, 0x9, 0xff, 00, 0xd5, 0xcf, + 0x1c, 0x9f, 0xee, 0xb8, 0x34, 0x1, 0x35, 0x14, 0x51, 0x40, + 0x5, 0x14, 0x51, 0x40, 0x5, 0x14, 0x51, 0x40, 0x5, 0x14, + 0x51, 0x40, 0x5, 0x23, 0x28, 0x60, 0x41, 00, 0x83, 0xd4, + 0x1a, 0x5a, 0x28, 0x3, 0x97, 0xd5, 0xbe, 0x19, 0x78, 0x5b, + 0x5b, 0x2c, 0xd7, 0x5a, 0x25, 0xae, 0xf6, 0xeb, 0x24, 0x4b, + 0xe5, 0x31, 0xfc, 0x57, 0x15, 0xc5, 0xea, 0xff, 00, 0xb3, + 0x7e, 0x83, 0x76, 0x4b, 0x58, 0x5e, 0xdd, 0xd8, 0x1e, 0xca, + 0xc4, 0x4a, 0xbf, 0xae, 0xf, 0xeb, 0x5e, 0xb9, 0x45, 0x79, + 0xd5, 0xb2, 0xec, 0x1e, 0x23, 0xf8, 0x94, 0x93, 0xf9, 0x59, + 0xfd, 0xe8, 0xc2, 0x74, 0x29, 0x4f, 0xe2, 0x8a, 0x3e, 0x7b, + 0xbd, 0xfd, 0x99, 0xb5, 0x38, 0xf2, 0x6d, 0x35, 0x9b, 0x59, + 0x87, 0x61, 0x34, 0x4d, 0x1f, 0xf2, 0xdd, 0x58, 0x17, 0xbf, + 0xb3, 0xff, 00, 0x8b, 0xad, 0x9, 0xf2, 0xe0, 0xb5, 0xbb, + 0x3, 0xbc, 0x33, 0x8f, 0xfd, 0x9b, 0x15, 0xf5, 0x1d, 0x15, + 0xe4, 0x54, 0xe1, 0xcc, 0x4, 0xfe, 0x14, 0xd7, 0xa3, 0xff, + 00, 0x3b, 0x9c, 0xb2, 0xc0, 0x51, 0x7b, 0x68, 0x7c, 0x87, + 0x3f, 0xc2, 0x3f, 0x18, 0x5b, 0xe7, 0x76, 0x83, 0x72, 0xc3, + 0xd5, 0xa, 0xb7, 0xf2, 0x35, 0x49, 0xfe, 0x1d, 0x78, 0xa2, + 0x33, 0xcf, 0x87, 0xf5, 0x1f, 0xc2, 0xd9, 0xcf, 0xf4, 0xaf, + 0xb2, 0x68, 0xae, 0x27, 0xc2, 0xd8, 0x6e, 0x95, 0x25, 0xf8, + 0x7f, 0x91, 0x93, 0xcb, 0xa1, 0xd2, 0x4c, 0xf8, 0xd0, 0x7c, + 0x3d, 0xf1, 0x3b, 0x1e, 0x3c, 0x3f, 0xa9, 0x7f, 0xe0, 0x2b, + 0xff, 00, 0x85, 0x5c, 0xb7, 0xf8, 0x53, 0xe2, 0xeb, 0xaf, + 0xb9, 0xa0, 0x5d, 0x8f, 0xfa, 0xe8, 0x2, 0x7f, 0xe8, 0x44, + 0x57, 0xd7, 0xf4, 0x50, 0xb8, 0x5b, 0xf, 0xd6, 0xa4, 0xbf, + 0xf, 0xf2, 0x5, 0x97, 0x43, 0xac, 0x99, 0xf2, 0xe6, 0x9f, + 0xf0, 0x3, 0xc5, 0xb7, 0xa4, 0x79, 0xb0, 0x5b, 0x59, 0x2f, + 0xac, 0xf3, 0x83, 0xfa, 0x2e, 0x6b, 0xa9, 0xd2, 0xbf, 0x66, + 0x59, 0x4b, 0x2b, 0x6a, 0x5a, 0xda, 0x2a, 0xf7, 0x4b, 0x58, + 0x72, 0x7f, 0xef, 0xa6, 0x3f, 0xd2, 0xbd, 0xea, 0x8a, 0xef, + 0xa5, 0xc3, 0xb8, 0xa, 0x7a, 0xca, 0x2e, 0x5e, 0xaf, 0xfc, + 0xac, 0x6d, 0x1c, 0xd, 0x18, 0xee, 0xae, 0x71, 0x5e, 0x1e, + 0xf8, 0x3d, 0xe1, 0x6f, 0xe, 0xec, 0x78, 0xf4, 0xd5, 0xbc, + 0xb8, 0x5e, 0x7c, 0xeb, 0xc3, 0xe6, 0x1c, 0xfa, 0xe0, 0xf0, + 0x3f, 0x1, 0x5d, 0xa0, 0x1, 0x40, 00, 0x60, 0xe, 0x80, + 0x52, 0xd1, 0x5e, 0xfd, 0x1a, 0x14, 0xb0, 0xf1, 0xe5, 0xa5, + 0x15, 0x15, 0xe4, 0x8e, 0xd8, 0xc2, 0x30, 0x56, 0x8a, 0xb0, + 0x51, 0x45, 0x15, 0xb9, 0x61, 0x45, 0x14, 0x50, 0x1, 0x45, + 0x14, 0x50, 0x7, 0x1, 0xf1, 0xa6, 0xef, 0xec, 0xde, 0x11, + 0x7f, 0x73, 0x5f, 0xa, 0x6b, 0x72, 0x79, 0x97, 0x97, 0xc, + 0x7b, 0xb1, 0xaf, 0xb5, 0x7f, 0x68, 0x1b, 0x9f, 0x27, 0xc3, + 0x8, 0x9e, 0xb9, 0x35, 0xf1, 0x1e, 0xa8, 0xfb, 0xa4, 0x94, + 0xfa, 0xb1, 0xaf, 0xce, 0xf3, 0xd9, 0x73, 0x63, 0x23, 0x1e, + 0xc8, 0xfc, 0xfb, 0x89, 0x67, 0xef, 0x24, 0x78, 0x67, 0xc7, + 0x2b, 0x8d, 0x9a, 0x5c, 0xe3, 0xfd, 0x93, 0xfc, 0xab, 0xf5, + 0x97, 0xf6, 0x7f, 0xd2, 0x46, 0x85, 0xf0, 0x37, 0xc0, 0x16, + 0xb, 0x9c, 0x41, 0xa1, 0x59, 0xaf, 0x3e, 0xbe, 0x4a, 0xe6, + 0xbf, 0x22, 0xfe, 0x38, 0x39, 0x9a, 0x23, 0xa, 0xe5, 0x9a, + 0x46, 0x8, 00, 0xea, 0x49, 0xe2, 0xbf, 0x68, 0x3c, 0x33, + 0x62, 0x9a, 0x5f, 0x86, 0xf4, 0xab, 0x38, 0xc6, 0xd4, 0xb7, + 0xb4, 0x8a, 0x25, 0x7, 0xb0, 0x54, 0x3, 0xfa, 0x57, 0xd5, + 0xe5, 0x6a, 0xd4, 0x51, 0x5c, 0x1d, 0x1b, 0x61, 0x27, 0x2e, + 0xf2, 0x66, 0x9d, 0x14, 0x51, 0x5e, 0xc9, 0xf7, 0xe7, 0xe7, + 0xef, 0xc5, 0xdf, 0x13, 0x3f, 0x8b, 0x3e, 0x26, 0xf8, 0x82, + 0xf9, 0xf8, 0xb, 0x72, 0x6d, 0x90, 0x7a, 0x2c, 0x7f, 0x20, + 0xff, 00, 0xd0, 0x49, 0xfc, 0x6b, 0xdc, 0xbf, 0x64, 0xbf, + 0x8, 0xf9, 0x76, 0xd7, 0xda, 0xe4, 0xa9, 0xc9, 0x3e, 0x54, + 0x44, 0xfe, 0xb5, 0xf3, 0x7d, 0xfc, 0x6f, 0xa9, 0xf8, 0xdf, + 0x58, 0x86, 0x31, 0xba, 0x49, 0x35, 0x3b, 0x85, 00, 0x7a, + 0xf9, 0xad, 0x5f, 0x7c, 0x7c, 0x35, 0xf0, 0xd2, 0x78, 0x53, + 0xc1, 0x9a, 0x6d, 0x82, 0xa0, 0x46, 0x58, 0x83, 0x3f, 0xfb, + 0xc4, 0x57, 0xc1, 0x65, 0x94, 0x25, 0x5f, 0x30, 0x95, 0x59, + 0xfd, 0x9b, 0xbf, 0x9b, 0x3f, 0x39, 0xe1, 0xfa, 0x6f, 0x17, + 0x89, 0x9e, 0x2a, 0x7d, 0x2e, 0xfe, 0x6c, 0xea, 0x28, 0xa2, + 0x8a, 0xfb, 0xd3, 0xf4, 0x60, 0xa2, 0x8a, 0x28, 00, 0xa2, + 0x9a, 0xe8, 0x1c, 0x60, 0xe7, 0xd7, 0x83, 0x8a, 0x5c, 0x7b, + 0x9a, 00, 0xaf, 0x73, 0xa6, 0xda, 0x5e, 0x29, 0x17, 0x16, + 0xb0, 0xce, 0xf, 0x69, 0x23, 0xd, 0xfc, 0xc5, 0x4f, 0x1c, + 0x49, 0xc, 0x6b, 0x1c, 0x68, 0xb1, 0xc6, 0x80, 0x2a, 0xaa, + 0x8c, 00, 0x7, 0x40, 0x5, 0x3a, 0x8a, 00, 0x28, 0xa2, + 0x8a, 00, 0x28, 0xa2, 0x8a, 00, 0x28, 0xa2, 0x8a, 00, + 0x28, 0xa2, 0x8a, 00, 0x28, 0xa2, 0x8a, 00, 0x28, 0xa2, + 0x8a, 00, 0x28, 0xa2, 0x8a, 00, 0x46, 0x50, 0xc3, 0x4, + 0x2, 0x3d, 0xd, 0x67, 0x5e, 0x78, 0x6b, 0x48, 0xd4, 0x3f, + 0xe3, 0xeb, 0x4a, 0xb2, 0xb9, 0xff, 00, 0xae, 0xd6, 0xe8, + 0xff, 00, 0xcc, 0x56, 0x95, 0x14, 0x1, 0xc5, 0x6a, 0x9f, + 0x4, 0xfe, 0x1e, 0xeb, 0x60, 0x8d, 0x43, 0xc0, 0xde, 0x1c, + 0xbd, 0xdd, 0xd7, 0xcf, 0xd2, 0xa0, 0x7c, 0xfe, 0x6b, 0x5c, + 0xa6, 0xa7, 0xfb, 0x1f, 0x7c, 0x10, 0xd6, 0x14, 0x8b, 0xbf, + 0x85, 0x5e, 0x13, 0x70, 0x7a, 0xec, 0xd2, 0xa2, 0x4f, 0xfd, + 0x4, 0xa, 0xf6, 0xa, 0x28, 0x3, 0xe7, 0x4d, 0x57, 0xfe, + 0x9, 0xe5, 0xfb, 0x3c, 0x6a, 0xe0, 0x89, 0x7e, 0x18, 0x69, + 0x50, 0xe7, 0xfe, 0x7d, 0x64, 0x9a, 0xf, 0xfd, 0x1, 0xc5, + 0x72, 0xb7, 0x9f, 0xf0, 0x4a, 0xff, 00, 0xd9, 0xbe, 0xe8, + 0xb1, 0x5f, 0x5, 0xdd, 0xdb, 0x13, 0xff, 00, 0x3c, 0x75, + 0xab, 0xce, 0x3f, 0x3, 0x29, 0x15, 0xf5, 0xad, 0x14, 0x1, + 0xf1, 0x76, 0xa3, 0xff, 00, 0x4, 0x8e, 0xfd, 0x9f, 0x6f, + 0x50, 0xac, 0x1a, 0x7e, 0xbf, 0xa7, 0x9f, 0xef, 0x41, 0xab, + 0xbb, 0x1f, 0xfc, 0x7c, 0x35, 0x72, 0xba, 0x97, 0xfc, 0x11, + 0x97, 0xe0, 0xe5, 0xca, 0x9f, 0xb1, 0x78, 0x93, 0xc5, 0xd6, + 0x4d, 0xfe, 0xd5, 0xd5, 0xbc, 0x80, 0x7e, 0x70, 0x8a, 0xfb, + 0xee, 0x8a, 0x5, 0x64, 0x7e, 0x6d, 0xea, 0x1f, 0xf0, 0x44, + 0xdf, 0x5, 0xbc, 0x6d, 0xf6, 0x1f, 0x89, 0x1a, 0xf4, 0x2f, + 0xfc, 0x3f, 0x68, 0xb3, 0x82, 0x40, 0x3f, 0x2d, 0xb5, 0xc8, + 0xea, 0x1f, 0xf0, 0x44, 0x5b, 0x80, 0x18, 0xd8, 0xfc, 0x58, + 0x8c, 0x9f, 0xe1, 0x5b, 0x8d, 0x10, 0x8f, 0xcc, 0x89, 0xbf, + 0xa5, 0x7e, 0xa9, 0x51, 0x4c, 0x2c, 0x8f, 0xc8, 0x5b, 0xff, + 00, 0xf8, 0x22, 0x7f, 0x8e, 0xe2, 0xc, 0x6c, 0xfe, 0x22, + 0xf8, 0x7e, 0xe3, 0xfb, 0xa2, 0x6b, 0x49, 0xe3, 0xcf, 0xe5, + 0xba, 0xb9, 0x1d, 0x43, 0xfe, 0x8, 0xd9, 0xf1, 0xba, 0xd9, + 0x9b, 0xec, 0xba, 0xcf, 0x83, 0xef, 0x10, 0x74, 0xcd, 0xfc, + 0xf1, 0xb1, 0xfc, 0xc, 0x18, 0xfd, 0x6b, 0xf6, 0xa2, 0x8a, + 0x2e, 0x16, 0x47, 0xe1, 0xd5, 0xd7, 0xfc, 0x12, 0x2b, 0xf6, + 0x81, 0xb7, 0x56, 0x29, 0x69, 0xe1, 0xcb, 0x9c, 0x76, 0x8b, + 0x56, 0x19, 0x3f, 0xf7, 0xd2, 0xa, 0xe6, 0x35, 0x1f, 0xf8, + 0x25, 0xef, 0xed, 0x1b, 0x60, 0x5b, 0x6f, 0x81, 0xa2, 0xbc, + 0xb, 0xde, 0xdb, 0x55, 0xb5, 0x39, 0xfa, 0x66, 0x40, 0x6b, + 0xf7, 0xb2, 0x8a, 0x2e, 0x2e, 0x54, 0x7f, 0x3d, 0x77, 0xdf, + 0xf0, 0x4f, 0xdf, 0xda, 0x1b, 0x4f, 0x24, 0x49, 0xf0, 0xb3, + 0x59, 0x7c, 0x77, 0x80, 0xc5, 0x2f, 0xfe, 0x82, 0xe6, 0xb9, + 0x2d, 0x53, 0xf6, 0x4e, 0xf8, 0xd1, 0xa3, 0xbb, 0x25, 0xd7, + 0xc2, 0xdf, 0x16, 0x23, 0x2f, 0x5f, 0x2f, 0x48, 0x9a, 0x4f, + 0xfd, 0x5, 0x4d, 0x7f, 0x48, 0x34, 0x51, 0x70, 0xe5, 0x3f, + 0x99, 0x4d, 0x47, 0xe1, 0xf, 0x8e, 0xf4, 0x76, 0x2b, 0x7d, + 0xe0, 0xaf, 0x11, 0x59, 0xb0, 0xea, 0x27, 0xd2, 0xa7, 0x4c, + 0x7e, 0x69, 0x5c, 0xf5, 0xe6, 0x8d, 0xa8, 0x69, 0xcc, 0x56, + 0xee, 0xc6, 0xe6, 0xd4, 0x8e, 0xa2, 0x68, 0x59, 0x3f, 0x98, + 0xaf, 0xea, 0x2c, 0x80, 0x7a, 0x8a, 0xad, 0x71, 0xa5, 0x59, + 0x5d, 0xff, 00, 0xaf, 0xb3, 0xb7, 0x9b, 0xfe, 0xba, 0x44, + 0xad, 0xfc, 0xc5, 0x17, 0xe, 0x53, 0xf9, 0x70, 0xc8, 0xf5, + 0xa5, 0xaf, 0xe9, 0xe6, 0xeb, 0xe1, 0xf7, 0x85, 0xaf, 0xb3, + 0xf6, 0x9f, 0xd, 0x69, 0x17, 0x19, 0xeb, 0xe6, 0xd8, 0x44, + 0xd9, 0xfc, 0xd6, 0xb9, 0xcd, 0x4f, 0xf6, 0x78, 0xf8, 0x5b, + 0xac, 0xe7, 0xed, 0xdf, 0xe, 0xbc, 0x2d, 0x73, 0x9e, 0xbe, + 0x66, 0x91, 0x1, 0xcf, 0xfe, 0x39, 0x45, 0xc5, 0xca, 0x7f, + 0x35, 0x34, 0x57, 0xf4, 0x53, 0xa8, 0xfe, 0xc4, 0x7f, 0x1, + 0x75, 0x56, 0x2d, 0x3f, 0xc2, 0x7f, 0xb, 0x86, 0x3d, 0x4c, + 0x36, 0xb, 0x17, 0xfe, 0x83, 0x8a, 0xe5, 0xb5, 0x3f, 0xf8, + 0x26, 0xf7, 0xec, 0xeb, 0xaa, 0x67, 0x77, 0xc3, 0x8b, 0x4b, + 0x62, 0x7f, 0xe7, 0xd6, 0xee, 0xe2, 0x2f, 0xe5, 0x25, 0x17, + 0xe, 0x53, 0xf9, 0xff, 00, 0xa2, 0xbf, 0x75, 0x35, 0x5f, + 0xf8, 0x24, 0xf7, 0xec, 0xf1, 0xa8, 0xee, 0x31, 0x78, 0x7f, + 0x56, 0xd3, 0xc9, 0xef, 0x6b, 0xab, 0xcd, 0xc7, 0xe0, 0xe5, + 0xab, 0x91, 0xd4, 0x3f, 0xe0, 0x8d, 0x9f, 0x5, 0x2e, 0x77, + 0x7d, 0x9b, 0x5a, 0xf1, 0x75, 0x91, 0x3d, 0x36, 0xdf, 0x42, + 0xe0, 0x7f, 0xdf, 0x50, 0xd3, 0xb8, 0x72, 0x9f, 0x8b, 0x34, + 0x57, 0xec, 0x35, 0xd7, 0xfc, 0x11, 0x53, 0xe1, 0x9b, 0x83, + 0xf6, 0x7f, 0x1e, 0x78, 0xae, 0x13, 0xdb, 0xcc, 0x5b, 0x67, + 0x3, 0xf2, 0x8c, 0x57, 0x3f, 0xa8, 0x7f, 0xc1, 0x12, 0x7c, + 0x3a, 0xc0, 0xfd, 0x87, 0xe2, 0x8e, 0xa9, 0x19, 0xec, 0x2e, + 0x34, 0xb8, 0xdf, 0xf5, 0xe, 0x28, 0xb8, 0xac, 0xcf, 0xc9, + 0x9a, 0x2b, 0xf4, 0xeb, 0x51, 0xff, 00, 0x82, 0x23, 0x6a, + 0xe1, 0x98, 0xd8, 0x7c, 0x56, 0xb2, 0x65, 0xec, 0xb7, 0x1a, + 0x33, 0x83, 0xf9, 0x89, 0x4f, 0xf2, 0xae, 0x5b, 0x52, 0xff, + 00, 0x82, 0x2b, 0x7c, 0x4a, 0x81, 0x8f, 0xd8, 0x7c, 0x75, + 0xe1, 0x8b, 0xb5, 0x1d, 0x3c, 0xe4, 0xb8, 0x88, 0x9f, 0xc9, + 0x1a, 0x8b, 0x85, 0x99, 0xf9, 0xdd, 0x49, 0x5f, 0x73, 0xea, + 0x7f, 0xf0, 0x47, 0x7f, 0x8e, 0x76, 0x84, 0xfd, 0x92, 0xf7, + 0xc2, 0xb7, 0xeb, 0xfe, 0xce, 0xa3, 0x22, 0x1f, 0xfc, 0x7a, + 0x2a, 0xe3, 0xb5, 0x4f, 0xf8, 0x25, 0x87, 0xed, 0x1b, 0xa7, + 0x48, 0x56, 0x2f, 0x7, 0xd9, 0xea, 00, 0x7f, 0x1d, 0xae, + 0xaf, 0x6d, 0x83, 0xff, 00, 0x7d, 0xba, 0x9a, 0x2e, 0x16, + 0x67, 0xc9, 0x40, 0xed, 0x39, 0x1c, 0x1f, 0x51, 0x5a, 0xda, + 0x77, 0x8b, 0xb5, 0xdd, 0x1d, 0x81, 0xb0, 0xd6, 0xb5, 0x1b, + 0x12, 0x3a, 0x1b, 0x6b, 0xb9, 0x23, 0xc7, 0xe4, 0x45, 0x7b, + 0xe5, 0xdf, 0xfc, 0x13, 0x8f, 0xf6, 0x8e, 0xb3, 0x7d, 0xad, + 0xf0, 0xc2, 0xfe, 0x4f, 0x78, 0x6f, 0x2d, 0x5c, 0x7e, 0x92, + 0xd6, 0xe, 0xa3, 0xfb, 0xc, 0x7c, 0x7e, 0xd2, 0x89, 0x13, + 0xfc, 0x28, 0xf1, 0x23, 0x63, 0xbc, 0x16, 0xbe, 0x70, 0xfc, + 0xd0, 0x9a, 0x3, 0x53, 0x85, 0xb0, 0xf8, 0xf3, 0xf1, 0x2f, + 0x4b, 0x60, 0xd6, 0x9f, 0x10, 0x7c, 0x53, 0x6e, 0x47, 0x4d, + 0x9a, 0xcd, 0xc0, 0xc7, 0xfe, 0x3f, 0x5d, 0x4e, 0x9f, 0xfb, + 0x63, 0xfc, 0x71, 0xd2, 0xd9, 0x4d, 0xbf, 0xc5, 0x5f, 0x15, + 0x64, 0x74, 0xf3, 0x75, 0x29, 0x25, 0x1f, 0x93, 0x13, 0x58, + 0xfa, 0xaf, 0xec, 0xcb, 0xf1, 0x73, 0x44, 0x24, 0x5e, 0xfc, + 0x32, 0xf1, 0x64, 0x4, 0x7a, 0xe8, 0xd7, 0x7, 0xf9, 0x25, + 0x73, 0x1a, 0x9f, 0xc3, 0x3f, 0x18, 0x68, 0x80, 0x9d, 0x47, + 0xc2, 0x7a, 0xe5, 0x80, 0x1d, 0x4d, 0xd6, 0x9b, 0x34, 0x7f, + 0xfa, 0x12, 0x8a, 0x3, 0x53, 0xda, 0x6c, 0x7f, 0xe0, 0xa2, + 0x5f, 0xb4, 0x55, 0x86, 0xd0, 0xbf, 0x13, 0xf5, 0x39, 0x40, + 0xed, 0x3c, 0x16, 0xf2, 0x7f, 0x38, 0xeb, 0xa8, 0xd3, 0xbf, + 0xe0, 0xa9, 0xdf, 0xb4, 0x66, 0x9e, 0x81, 0x4f, 0x8c, 0x6d, + 0x2e, 0xc0, 0xff, 00, 0x9f, 0x8d, 0x22, 0xd5, 0x89, 0xfc, + 0x42, 0x3, 0x5f, 0x28, 0x4f, 0x65, 0x71, 0x6a, 0x71, 0x34, + 0x12, 0xc2, 0x7f, 0xe9, 0xa2, 0x15, 0xfe, 0x75, 0x6, 0x47, + 0xad, 0x1, 0x76, 0x7d, 0xb1, 0x67, 0xff, 00, 0x5, 0x79, + 0xf8, 0xff, 00, 0x6a, 0xa0, 0x49, 0x37, 0x86, 0xae, 0xcf, + 0xf7, 0xa6, 0xd2, 0x70, 0x4f, 0xfd, 0xf2, 0xeb, 0x5b, 0x96, + 0x3f, 0xf0, 0x59, 0x6f, 0x8d, 0x76, 0xe0, 0xb, 0x8d, 0x7, + 0xc1, 0xb7, 0x63, 0xb9, 0x36, 0x37, 0x8, 0x4f, 0xe5, 0x3d, + 0x7c, 0x19, 0x45, 0x16, 0xb, 0xb3, 0xf4, 0x7f, 0x4a, 0xff, + 00, 0x82, 0xd8, 0x78, 0xe6, 0x8, 0xf1, 0xa8, 0xfc, 0x39, + 0xd0, 0x2f, 0x1f, 0xfb, 0xd6, 0xf7, 0x93, 0x40, 0x3f, 0x22, + 0x1e, 0xba, 0x8d, 0x27, 0xfe, 0xb, 0x73, 0x37, 0xfc, 0xc4, + 0xfe, 0x14, 0x47, 0xff, 00, 0x6e, 0x9a, 0xc9, 0xff, 00, + 0xd9, 0xa1, 0xaf, 0xcb, 0x8a, 0x28, 0xb0, 0x5d, 0x9f, 0xad, + 0xfa, 0x5f, 0xfc, 0x16, 0xcf, 0xc2, 0x12, 0x11, 0xfd, 0xa3, + 0xf0, 0xd3, 0x5b, 0xb7, 0x1d, 0xcd, 0xad, 0xf4, 0x32, 0xff, + 00, 0xe8, 0x41, 0x6b, 0xa8, 0xd3, 0x3f, 0xe0, 0xb3, 0xdf, + 0x8, 0xae, 0xdc, 0xb, 0xbf, 0xa, 0xf8, 0xb6, 0xc4, 0x7f, + 0x78, 0xc1, 0x6f, 0x27, 0xf2, 0x96, 0xbf, 0x1a, 0x28, 0xa2, + 0xc1, 0xcc, 0xcf, 0xdc, 0x3b, 0x1f, 0xf8, 0x2b, 0xb7, 0xec, + 0xff, 00, 0x76, 0x47, 0x9d, 0x75, 0xe2, 0x3b, 0x2f, 0x79, + 0xb4, 0x92, 0x7f, 0xf4, 0x6, 0x6a, 0xdc, 0xb3, 0xff, 00, + 0x82, 0xaa, 0x7e, 0xce, 0x57, 0x6c, 0x14, 0xf8, 0xbe, 0xfa, + 0xdf, 0x3d, 0xe6, 0xd1, 0xae, 0x80, 0x1f, 0x94, 0x66, 0xbf, + 0x8, 0x28, 0xa2, 0xc3, 0xe6, 0x3f, 0xa0, 0xd, 0x3f, 0xfe, + 0xa, 0x47, 0xfb, 0x39, 0x6a, 0x2c, 0x15, 0x3e, 0x25, 0x5a, + 0x42, 0x4f, 0xfc, 0xfc, 0x59, 0x5d, 0x44, 0x3f, 0x36, 0x88, + 0xa, 0xea, 0x6c, 0x3f, 0x6d, 0xef, 0x80, 0x9a, 0x88, 0x5f, + 0x27, 0xe2, 0xcf, 0x85, 0x81, 0x6e, 0x82, 0x5d, 0x41, 0x63, + 0x3f, 0x93, 0x62, 0xbf, 0x9d, 0x6a, 0x29, 0x58, 0x39, 0x8f, + 0xe9, 0x53, 0x4e, 0xfd, 0xa2, 0xfe, 0x16, 0x6a, 0xca, 0xd, + 0x9f, 0xc4, 0x6f, 0xb, 0x4e, 0xf, 0x4d, 0xba, 0xc4, 0x1c, + 0xff, 00, 0xe3, 0xf5, 0xd3, 0xd8, 0x78, 0xf3, 0xc3, 0x5a, + 0xa8, 0x6, 0xcb, 0xc4, 0x3a, 0x55, 0xd8, 0x3d, 0xc, 0x17, + 0xb1, 0xbe, 0x7f, 0x26, 0xaf, 0xe6, 0x12, 0x95, 0x58, 0xa9, + 0xc8, 0x24, 0x1f, 0x6a, 0x2c, 0x1c, 0xc7, 0xf5, 0x23, 0xd, + 0xed, 0xbd, 0xc8, 0x6, 0x29, 0xe2, 0x94, 0x1f, 0xee, 0x38, + 0x3f, 0xca, 0xa6, 0xaf, 0xe5, 0xf2, 0xc7, 0xc5, 0x9a, 0xde, + 0x96, 00, 0xb3, 0xd6, 0x75, 0xb, 0x40, 0x3a, 0x79, 0x17, + 0x4e, 0x98, 0xfc, 0x8d, 0x6e, 0x5a, 0xfc, 0x66, 0xf8, 0x83, + 0x63, 0x8f, 0xb3, 0x78, 0xef, 0xc4, 0xd6, 0xf8, 0xe9, 0xe5, + 0x6b, 0x17, 0xb, 0xfc, 0x9e, 0x8b, 0xf, 0x98, 0xfe, 0x99, + 0xe8, 0xaf, 0xe6, 0xd6, 0xc7, 0xf6, 0xa0, 0xf8, 0xc1, 0xa6, + 0xe3, 0xec, 0xff, 00, 0x14, 0x3c, 0x5c, 0x98, 0xe9, 0x9d, + 0x6a, 0xe1, 0xbf, 0x9b, 0x9a, 0xe9, 0xb4, 0xef, 0xdb, 0x9f, + 0xe3, 0xf6, 0x96, 00, 0x83, 0xe2, 0xbf, 0x88, 0xc8, 0x1d, + 0xa6, 0xb9, 0x12, 0xff, 00, 0xe8, 0x60, 0xd1, 0x60, 0xe6, + 0x3f, 0xa2, 0x4a, 0x2b, 0xf0, 0x7, 0x4d, 0xff, 00, 0x82, + 0x94, 0x7e, 0xd1, 0xba, 0x6e, 0x31, 0xf1, 0x1e, 0xe2, 0xe8, + 0xe, 0xd7, 0x36, 0x36, 0xaf, 0xfa, 0xf9, 0x79, 0xae, 0xb7, + 0x4c, 0xff, 00, 0x82, 0xb2, 0x7e, 0xd0, 0xba, 0x78, 0x51, + 0x2e, 0xb5, 0xa3, 0x5f, 0x81, 0xff, 00, 0x3f, 0x3a, 0x4c, + 0x79, 0x3f, 0xf7, 0xce, 0xda, 0x2c, 0x1c, 0xc8, 0xfd, 0xd1, + 0xa2, 0xbf, 0x16, 0x74, 0xdf, 0xf8, 0x2c, 0x9f, 0xc6, 0xbb, + 0x45, 0xb, 0x75, 0xa2, 0x78, 0x46, 0xfb, 0x1d, 0x59, 0xac, + 0xa7, 0x42, 0x7f, 0xef, 0x99, 0xb1, 0xfa, 0x57, 0xeb, 0x5f, + 0xc0, 0x9f, 0x1c, 0x6a, 0x7f, 0x13, 0x3e, 0xc, 0xf8, 0x2b, + 0xc5, 0xba, 0xcd, 0xb4, 0x16, 0x5a, 0xa6, 0xb7, 0xa4, 0xdb, + 0x6a, 0x17, 0x16, 0xf6, 0xc0, 0x88, 0xe3, 0x79, 0x23, 0xe, + 0x55, 0x72, 0x49, 0xc0, 0xcf, 0x73, 0x48, 0x77, 0xb9, 0xdd, + 0xd1, 0x45, 0x14, 0xc, 0x28, 0xa2, 0x8a, 00, 0xf1, 0x4f, + 0xda, 0x4e, 0xe7, 0xcb, 0xd1, 0xa1, 0x4c, 0xff, 00, 0x9, + 0x35, 0xf1, 0xa6, 0xa0, 0xdc, 0x39, 0xf5, 0x26, 0xbe, 0xb3, + 0xfd, 0xa7, 0x6e, 0xb6, 0xc0, 0x89, 0x9e, 0x89, 0x8a, 0xf9, + 0x23, 0x51, 0x6c, 0x46, 0xdf, 0x8d, 0x7e, 0x69, 0x9b, 0x3e, + 0x7c, 0xc2, 0x5e, 0x56, 0x3f, 0x31, 0xe2, 0x59, 0xfe, 0xf4, + 0xf0, 0xdf, 0x1d, 0xc4, 0xda, 0x9f, 0x8e, 0x3c, 0x39, 0x62, + 0x83, 0x73, 0xdc, 0xea, 0xd6, 0xb0, 0x85, 0xf5, 0x2d, 0x2a, + 0xc, 0x7e, 0xb5, 0xfb, 0x56, 00, 00, 0x1, 0xd0, 0x57, + 0xe3, 0x1d, 0x9d, 0xa3, 0xeb, 0x5f, 0xb4, 0x7, 0xc3, 0x8b, + 0x18, 0xcf, 0xcf, 0x2f, 0x89, 0x6c, 0x3f, 0x49, 0xd1, 0x8f, + 0xf2, 0xaf, 0xd9, 0xda, 0xfb, 0x8c, 0xbd, 0x5a, 0x8a, 0x3d, + 0xae, 0x13, 0x8f, 0x2e, 0x5a, 0x9f, 0x76, 0xc2, 0x8a, 0x28, + 0xaf, 0x4c, 0xfb, 0x43, 0xf3, 0xa6, 0xf6, 0x59, 0x3e, 0x1f, + 0x7c, 0x74, 0xd7, 0xac, 0xb5, 0x48, 0xb6, 0xc9, 0x6d, 0xa9, + 0xc9, 0x72, 0x23, 0x27, 0x21, 0x92, 0x43, 0xe6, 0x21, 0xfc, + 0x98, 0x57, 0xd7, 0x5a, 0x47, 0xed, 0x13, 0xe1, 0xdb, 0x8b, + 0x48, 0x7c, 0xd9, 0x15, 0x1f, 0x68, 0xc8, 0xd, 0xd3, 0x8a, + 0xf0, 0x9f, 0xdb, 0xc7, 0xe1, 0x85, 0xed, 0x86, 0xa5, 0xa7, + 0x7c, 0x48, 0xd2, 0xd5, 0x9e, 0x25, 0x44, 0xb1, 0xd4, 0x63, + 0x41, 0xf7, 0x70, 0x4f, 0x97, 0x21, 0xf6, 0xe7, 0x69, 0x3f, + 0xee, 0xd7, 0xce, 0xfe, 0x1f, 0xf1, 0x7c, 0x37, 0xf1, 0x28, + 0xf3, 0x36, 0xc9, 0xdd, 0x49, 0xaf, 0x8a, 0xaf, 0xf5, 0x9c, + 0xb6, 0xac, 0xe5, 0x87, 0xd5, 0x33, 0xf2, 0x6f, 0xaf, 0xd5, + 0xe1, 0xcc, 0x55, 0x5c, 0x2b, 0x8f, 0xb8, 0xdd, 0xd3, 0xf2, + 0x67, 0xe8, 0xc4, 0x3f, 0x1c, 0x7c, 0x33, 0x2f, 0xfc, 0xbd, + 0x1, 0xff, 00, 0x2, 0x15, 0xa1, 0x7, 0xc5, 0x9f, 0xe, + 0x4f, 0xd2, 0xf5, 0x47, 0xe3, 0x5f, 0x9f, 0xb0, 0xea, 0x21, + 0xc6, 0x44, 0xa4, 0x7e, 0x35, 0x65, 0x35, 0x29, 0xd7, 0xee, + 0xdc, 0xb8, 0xfa, 0x35, 0x72, 0x2c, 0xff, 00, 0x15, 0x1f, + 0x8a, 0x8, 0xf6, 0x21, 0xc4, 0xf2, 0x7f, 0x65, 0x1f, 0xa0, + 0xd0, 0xfc, 0x44, 0xd0, 0x26, 0xc6, 0x2f, 0xe3, 0xe7, 0xde, + 0xae, 0x47, 0xe2, 0xfd, 0x1e, 0x50, 0xa, 0xdf, 0xc2, 0x73, + 0xfe, 0xd5, 0x7e, 0x7a, 0x26, 0xb9, 0x7d, 0x18, 0xf9, 0x6f, + 0x25, 0x1f, 0xf0, 0x3a, 0xb5, 0x1f, 0x8b, 0x35, 0x68, 0xbe, + 0xed, 0xfc, 0xdf, 0xf7, 0xd5, 0x6c, 0xb8, 0x8a, 0xaa, 0xf8, + 0xa9, 0xaf, 0xbc, 0xea, 0x8f, 0x12, 0xc7, 0xac, 0xf, 0xd0, + 0xa4, 0xd7, 0xf4, 0xe9, 0x3e, 0xed, 0xe4, 0x27, 0xfe, 0x5, + 0x53, 0xae, 0xa3, 0x6a, 0xdd, 0x2e, 0x22, 0x3f, 0x47, 0x15, + 0xf9, 0xf3, 0x17, 0x8f, 0xf5, 0xd8, 0x47, 0xcb, 0x7f, 0x2f, + 0xe2, 0x6a, 0xf4, 0x3f, 0x15, 0x3c, 0x45, 0xf, 0x4b, 0xe7, + 0x3f, 0x8d, 0x6e, 0xb8, 0x8d, 0x7d, 0xaa, 0x7f, 0x89, 0xd1, + 0x1e, 0x23, 0xa0, 0xf7, 0x8b, 0x3e, 0xfd, 0x59, 0xe3, 0x6e, + 0x92, 0x29, 0xfa, 0x30, 0xa7, 0xee, 0x1e, 0xa2, 0xbe, 0xf, + 0xb7, 0xf8, 0xd9, 0xe2, 0x48, 0x31, 0xfe, 0x92, 0xcd, 0xf5, + 0x35, 0xa3, 0x6f, 0xfb, 0x40, 0xf8, 0x8a, 0x12, 0x33, 0x33, + 0x1c, 0x7a, 0x35, 0x6e, 0xb8, 0x8a, 0x8f, 0x58, 0x33, 0xa2, + 0x3c, 0x41, 0x85, 0x7b, 0xdc, 0xfb, 0x82, 0x8a, 0xf8, 0xd2, + 0xdb, 0xf6, 0x97, 0xd7, 0x62, 0x18, 0x62, 0xed, 0xff, 00, + 0x2, 0xad, 0x3b, 0x6f, 0xda, 0x93, 0x54, 0x4f, 0xbe, 0xae, + 0x7f, 0x1c, 0xd6, 0xeb, 0x3f, 0xc2, 0x3d, 0xee, 0xbe, 0x46, + 0xf1, 0xcf, 0x30, 0x72, 0xfb, 0x47, 0xd7, 0x14, 0x57, 0xcb, + 0x96, 0xff, 00, 0xb5, 0x64, 0xe0, 00, 0xf1, 0x37, 0xe4, + 0x2b, 0x52, 0xd7, 0xf6, 0xab, 0x84, 0xe3, 0xcd, 0x8b, 0xf3, + 0x15, 0xbc, 0x73, 0xbc, 0x13, 0xfb, 0x5f, 0x81, 0xd1, 0x1c, + 0xdb, 0x7, 0x2f, 0xb6, 0x7d, 0x1f, 0x45, 0x78, 0x34, 0x1f, + 0xb5, 0x2e, 0x9a, 0xff, 00, 0x7a, 0x35, 0x15, 0xab, 0x6b, + 0xfb, 0x4a, 0x68, 0x72, 0x91, 0xb8, 0x28, 0xff, 00, 0x81, + 0x62, 0xb7, 0x8e, 0x6d, 0x82, 0x97, 0xfc, 0xbc, 0x47, 0x44, + 0x73, 0xc, 0x34, 0xb6, 0x9a, 0x3d, 0x92, 0x8a, 0xf2, 0xdb, + 0x7f, 0xda, 0x7, 0xc3, 0xf3, 0x11, 0xf3, 0x81, 0xff, 00, + 0x3, 0x15, 0xa7, 0x7, 0xc6, 0xaf, 0xe, 0xcc, 0x33, 0xe7, + 0x81, 0xff, 00, 0x2, 0x15, 0xd1, 0x1c, 0x7e, 0x16, 0x5b, + 0x54, 0x46, 0xcb, 0x15, 0x46, 0x5b, 0x49, 0x1d, 0xfd, 0x15, + 0xc7, 0xc1, 0xf1, 0x53, 0xc3, 0xf3, 0x8e, 0x2e, 0xc0, 0xfa, + 0x91, 0x57, 0xe2, 0xf1, 0xee, 0x89, 0x30, 0x4, 0x5e, 0xa7, + 0xe7, 0x5b, 0xac, 0x45, 0x19, 0x6d, 0x35, 0xf7, 0x9a, 0xaa, + 0xb4, 0xde, 0xd2, 0x47, 0x43, 0x45, 0x64, 0xc7, 0xe2, 0xad, + 0x2a, 0x51, 0xf2, 0xde, 0xc5, 0xff, 00, 0x7d, 0x55, 0x95, + 0xd6, 0xac, 0x1f, 0xa5, 0xdc, 0x27, 0xfe, 0x6, 0x2b, 0x55, + 0x38, 0x3d, 0x99, 0x6a, 0x51, 0x7d, 0x4b, 0xb4, 0x54, 0x9, + 0x7d, 0x6f, 0x27, 0xdd, 0x9e, 0x33, 0xf4, 0x61, 0x52, 0x9, + 0xa3, 0x3d, 0x1d, 0x4f, 0xd0, 0xd5, 0x5d, 0xe, 0xe3, 0xe8, + 0xa4, 0x4, 0x1e, 0x87, 0x34, 0xb4, 0xc6, 0x14, 0x51, 0x45, + 00, 0x14, 0x51, 0x45, 00, 0x14, 0x51, 0x45, 00, 0x14, + 0x51, 0x45, 00, 0x14, 0x51, 0x45, 00, 0x14, 0x51, 0x45, + 00, 0x14, 0x51, 0x45, 00, 0x14, 0x51, 0x45, 00, 0x14, + 0x51, 0x45, 00, 0x14, 0x51, 0x45, 00, 0x14, 0x51, 0x45, + 00, 0x14, 0x51, 0x45, 00, 0x14, 0x51, 0x45, 00, 0x14, + 0x51, 0x45, 00, 0x14, 0x51, 0x45, 00, 0x14, 0xc7, 0x89, + 0x24, 0xfb, 0xe8, 0xad, 0xfe, 0xf0, 0xcd, 0x3e, 0x8a, 00, + 0xcb, 0xbc, 0xf0, 0xbe, 0x8d, 0xa8, 0x9c, 0xdd, 0xe9, 0x16, + 0x37, 0x47, 0xd6, 0x6b, 0x64, 0x7f, 0xe6, 0x2b, 0x9a, 0xd5, + 0xfe, 0x5, 0xfc, 0x38, 0xd7, 0xc1, 0xfe, 0xd2, 0xf0, 0x17, + 0x86, 0xaf, 0xb3, 0xd7, 0xed, 0x1a, 0x4c, 0xf, 0xfc, 0xd2, + 0xbb, 0x9a, 0x28, 0x3, 0xc7, 0x6f, 0x7f, 0x63, 0x9f, 0x81, + 0x9a, 0x89, 0x26, 0x7f, 0x84, 0x9e, 0xe, 0x24, 0xf7, 0x4d, + 0x1a, 0x4, 0x3f, 0xf8, 0xea, 0x8a, 0xc5, 0xd4, 0x3f, 0x60, + 0xaf, 0xd9, 0xf7, 0x52, 0x42, 0x92, 0xfc, 0x29, 0xf0, 0xfc, + 0x60, 0xf7, 0xb7, 0x85, 0xa1, 0x3f, 0x9a, 0x30, 0xaf, 0x7c, + 0xa2, 0x80, 0x3e, 0x5a, 0xd4, 0xff, 00, 0xe0, 0x99, 0x3f, + 0xb3, 0x96, 0xa4, 0xf, 0xfc, 0x5b, 0xf1, 0x68, 0x4f, 0xf1, + 0x5b, 0x6a, 0x57, 0x49, 0xff, 00, 0xb5, 0x48, 0xae, 0x4b, + 0x52, 0xff, 00, 0x82, 0x47, 0x7e, 0xcf, 0xf7, 0xa0, 0xf9, + 0x16, 0x1a, 0xf5, 0x81, 0xf5, 0x83, 0x56, 0x76, 0xff, 00, + 0xd0, 0xc1, 0xaf, 0xb4, 0xa8, 0xa0, 0x56, 0x3e, 0x1, 0xd5, + 0x7f, 0xe0, 0x8c, 0x9f, 0x8, 0x6e, 0xb2, 0x6c, 0xbc, 0x4d, + 0xe2, 0xcb, 0x3, 0xe8, 0x67, 0x82, 0x50, 0x3f, 0x38, 0xbf, + 0xad, 0x72, 0x9a, 0x9f, 0xfc, 0x11, 0x33, 0xc2, 0x32, 0x3, + 0xfd, 0x9f, 0xf1, 0x2f, 0x5a, 0x80, 0xf6, 0x17, 0x36, 0x10, + 0xc8, 0x3f, 0x42, 0xb5, 0xfa, 0x53, 0x45, 0x1, 0x64, 0x7e, + 0x56, 0x6a, 0x1f, 0xf0, 0x44, 0x4b, 0x92, 0x49, 0xb1, 0xf8, + 0xb7, 0x10, 0x1d, 0x85, 0xc6, 0x84, 0x4f, 0xea, 0x27, 0xac, + 0x2b, 0xcf, 0xf8, 0x22, 0x57, 0x8b, 0xa3, 0x52, 0x6d, 0x7e, + 0x27, 0x68, 0xb3, 0x9e, 0xc2, 0x5d, 0x36, 0x68, 0xf3, 0xf9, + 0x3b, 0x57, 0xeb, 0x85, 0x14, 0xee, 0x16, 0x47, 0xe3, 0x4e, + 0xa7, 0xff, 00, 0x4, 0x60, 0xf8, 0xb5, 0x6e, 0x9, 0xb1, + 0xf1, 0x5f, 0x85, 0x2f, 0x71, 0xd0, 0x3c, 0xb7, 0x11, 0x67, + 0xff, 00, 0x21, 0x1a, 0xe4, 0xf5, 0xf, 0xf8, 0x24, 0x47, + 0xc7, 0xfb, 0x36, 0x22, 0xb, 0x6f, 0xe, 0x5f, 0x1, 0xde, + 0xd, 0x58, 0x2e, 0x7f, 0xef, 0xb4, 0x5a, 0xfd, 0xc2, 0xa2, + 0x8b, 0x8a, 0xc8, 0xfc, 0x14, 0xd5, 0x3f, 0xe0, 0x97, 0x9f, + 0xb4, 0x76, 0x9a, 0x7e, 0x4f, 0x3, 0x45, 0x7d, 0xef, 0x6b, + 0xaa, 0xda, 0x9f, 0xfd, 0xa, 0x41, 0x5c, 0xed, 0xe7, 0xfc, + 0x13, 0xbf, 0xf6, 0x8b, 0xb1, 0xcf, 0x99, 0xf0, 0xb7, 0x54, + 0x7c, 0x7f, 0xcf, 0x1b, 0x8b, 0x69, 0x3f, 0xf4, 0x19, 0x4d, + 0x7f, 0x41, 0xb4, 0x51, 0x70, 0xe5, 0x47, 0xf3, 0xa5, 0xa9, + 0xfe, 0xc5, 0x3f, 0x1d, 0xf4, 0x8c, 0xfd, 0xa7, 0xe1, 0x4f, + 0x89, 0xf8, 0xff, 00, 0x9e, 0x36, 0x2d, 0x2f, 0xfe, 0x81, + 0x9a, 0xe5, 0xf5, 0x1f, 0xd9, 0xd7, 0xe2, 0xa6, 0x90, 0x9, + 0xbd, 0xf8, 0x6d, 0xe2, 0xcb, 0x60, 0x3a, 0x99, 0x34, 0x5b, + 0x91, 0xff, 00, 0xb2, 0x57, 0xf4, 0xab, 0x45, 0x17, 0xe, + 0x53, 0xf9, 0x81, 0xd4, 0xfc, 0x11, 0xe2, 0x3d, 0x10, 0x13, + 0xa8, 0xe8, 0x1a, 0xa5, 0x80, 0x1d, 0x7e, 0xd5, 0x65, 0x24, + 0x78, 0xff, 00, 0xbe, 0x94, 0x56, 0x29, 0xf9, 0x4e, 0xf, + 0x7, 0xd0, 0xd7, 0xf5, 0x25, 0x3d, 0x9c, 0x17, 0x23, 0x13, + 0x41, 0x1c, 0xbf, 0xef, 0xa0, 0x3f, 0xce, 0xb2, 0xb5, 0xf, + 0x3, 0xf8, 0x73, 0x57, 0x4d, 0xb7, 0xde, 0x1f, 0xd2, 0xef, + 0x57, 0xd2, 0xe2, 0xca, 0x39, 0x7, 0xea, 0xb4, 0x5c, 0x39, + 0x4f, 0xe6, 0xa, 0x8a, 0xfe, 0x95, 0xf5, 0x2f, 0xd9, 0xe7, + 0xe1, 0x6e, 0xae, 0x85, 0x2f, 0x7e, 0x1c, 0xf8, 0x56, 0xe5, + 0x4f, 0x50, 0xfa, 0x35, 0xb9, 0xff, 00, 0xd9, 0x2b, 0x99, + 0xbc, 0xfd, 0x8b, 0xfe, 0x4, 0x5f, 0x82, 0x25, 0xf8, 0x49, + 0xe1, 0x1e, 0x7a, 0x98, 0xf4, 0x98, 0xa3, 0x3f, 0x9a, 0x81, + 0x45, 0xc5, 0xca, 0x7f, 0x3a, 0x30, 0xc0, 0xf7, 0x33, 0x47, + 0xc, 0x4a, 0x5e, 0x49, 0x18, 0x22, 0xa8, 0xea, 0x49, 0x38, + 0x2, 0xbf, 0xa7, 0xf, 0x86, 0x5e, 0x1f, 0x1e, 0x14, 0xf8, + 0x6f, 0xe1, 0x5d, 0x10, 0x74, 0xd3, 0xb4, 0xab, 0x5b, 0x4e, + 0x98, 0xfb, 0x91, 0x2a, 0xff, 00, 0x4a, 0xf2, 0x56, 0xfd, + 0x81, 0xbf, 0x67, 0xef, 0x3e, 0x29, 0xe3, 0xf8, 0x5d, 0xa3, + 0x5b, 0xcd, 0x13, 0x89, 0x12, 0x4b, 0x7f, 0x32, 0x32, 0xac, + 0xe, 0x41, 0x1b, 0x5c, 0x77, 0xaf, 0x7e, 00, 0x28, 00, + 0x70, 0x5, 0x5, 0x25, 0x61, 0x68, 0xa2, 0x8a, 0x43, 0xa, + 0x28, 0xa2, 0x80, 0x3e, 0x65, 0xfd, 0xa7, 0xae, 0xf3, 0x74, + 0xc9, 0x9e, 0x80, 0xa, 0xf9, 0x6f, 0x55, 0x6c, 0x40, 0xdf, + 0x4a, 0xfa, 0x2b, 0xf6, 0x96, 0xbb, 0xdf, 0xab, 0xca, 0xb9, + 0xe8, 0xd8, 0xaf, 0x9b, 0xf5, 0xa7, 0xdb, 0x6c, 0xe7, 0xfd, + 0x93, 0x5f, 0x97, 0x63, 0x5f, 0x3e, 0x61, 0x37, 0xe6, 0x7e, + 0x49, 0xc4, 0x93, 0xbd, 0x59, 0x1c, 0x17, 0xc1, 0x6b, 0x21, + 0xad, 0xfe, 0xd7, 0xdf, 0xc, 0x2d, 0x58, 0xf0, 0xba, 0xbf, + 0xda, 0x3f, 0x18, 0xe2, 0x79, 0x7, 0xfe, 0x81, 0x5f, 0xb0, + 0x35, 0xf9, 0x3d, 0xfb, 0x20, 0x69, 0x8b, 0xad, 0xfe, 0xd9, + 0xde, 0x16, 0x2c, 0x37, 0xb, 0x1b, 0x7b, 0xcb, 0xb1, 0xec, + 0x44, 0x25, 0x41, 0xff, 00, 0xc7, 0xeb, 0xf5, 0x86, 0xbf, + 0x44, 0xc1, 0xab, 0x52, 0x47, 0xda, 0x70, 0xdc, 0x39, 0x32, + 0xca, 0x41, 0x45, 0x14, 0x57, 0x69, 0xf4, 0xe5, 0x1d, 0x6b, + 0x45, 0xb1, 0xf1, 0x1e, 0x93, 0x75, 0xa6, 0x6a, 0x56, 0xb1, + 0xde, 0xd8, 0x5d, 0x46, 0x62, 0x9a, 0x9, 0x57, 0x2a, 0xea, + 0x7a, 0x83, 0x5f, 0x9e, 0x3f, 0x1f, 0x3f, 0x63, 0x7d, 0x73, + 0xe1, 0xc6, 0xa7, 0x73, 0xac, 0x78, 0x5c, 0x4b, 0xa8, 0xf8, + 0x71, 0x98, 0xba, 0x94, 0x3b, 0xa5, 0xb5, 0x1f, 0xdd, 0x71, + 0xdc, 0xf, 0xef, 0x7e, 0x78, 0xaf, 0xd1, 0xca, 0x42, 0x3, + 0x2, 0x8, 0xc8, 0x3d, 0x41, 0xae, 0x6a, 0xd4, 0x15, 0x65, + 0xd9, 0x9e, 0x2e, 0x67, 0x94, 0xd0, 0xcd, 0x29, 0xa8, 0xd5, + 0xd1, 0xad, 0x9a, 0xe9, 0xfe, 0x6b, 0xc8, 0xfc, 0x79, 0x4f, + 0xf8, 0x49, 0xb4, 0xae, 0x1e, 0x13, 0x22, 0x8e, 0x3a, 0x73, + 0x52, 0xf, 0x16, 0x6a, 0xb0, 0xff, 00, 0xac, 0xb4, 0x90, + 0x7f, 0xc0, 0x4d, 0x7e, 0xa5, 0x78, 0xa7, 0xe0, 0xb7, 0x84, + 0x3c, 0x5b, 0xbd, 0xaf, 0x34, 0x88, 0xa1, 0x99, 0x8e, 0x4c, + 0xd6, 0xa0, 0x46, 0xc4, 0xfa, 0x9c, 0x70, 0x7f, 0x11, 0x5e, + 0x7f, 0x7f, 0xfb, 0x1e, 0xf8, 0x4a, 0xe9, 0xcb, 0x45, 0x77, + 0x77, 0x8, 0x3d, 0x1, 0x54, 0x6c, 0x7e, 0x82, 0xbc, 0xa, + 0x99, 0x75, 0x5b, 0xfc, 0x29, 0xfe, 0x7, 0xc4, 0xcf, 0x84, + 0x9c, 0x3e, 0x1d, 0x7d, 0x1d, 0xbf, 0x3, 0xf3, 0xe5, 0x7c, + 0x79, 0x75, 0x1f, 0xdf, 0xb7, 0x71, 0xf5, 0x6, 0xa6, 0x4f, + 0x88, 0xc4, 0x70, 0xc8, 0xc3, 0xf0, 0xaf, 0xb9, 0x6e, 0xff, + 00, 0x62, 0x6d, 0x12, 0x40, 0x7c, 0x9d, 0x65, 0xd4, 0xff, + 00, 0xb7, 0x6c, 0xf, 0xfe, 0xcd, 0x58, 0x57, 0x9f, 0xb0, + 0xcc, 0x4e, 0xf, 0x93, 0xac, 0xdb, 0x39, 0xf4, 0x78, 0xa, + 0x8f, 0xeb, 0x5c, 0xaf, 0x2e, 0x9f, 0x5a, 0x5f, 0x8a, 0xff, + 00, 0x33, 0x96, 0x5c, 0x2f, 0x5e, 0x3b, 0x29, 0x7d, 0xeb, + 0xfc, 0xcf, 0x8f, 0xe3, 0xf8, 0x8f, 0x9, 0xeb, 0xb8, 0x55, + 0xa8, 0xfe, 0x22, 0x5b, 0x37, 0xf1, 0xd7, 0xd2, 0x97, 0xff, + 00, 0xb0, 0xbe, 0xa6, 0xa7, 0xf7, 0x33, 0x69, 0xd3, 0x8f, + 0x5d, 0xc5, 0x7f, 0x9a, 0xd7, 0x3f, 0x7f, 0xfb, 0xe, 0x78, + 0x89, 0xf, 0xee, 0xec, 0x6d, 0xa7, 0xf7, 0x8e, 0x64, 0x1f, + 0xcc, 0x8a, 0xe7, 0x96, 0x5f, 0xde, 0x93, 0x39, 0xa5, 0xc3, + 0xf8, 0xa8, 0xec, 0xe5, 0xf7, 0x5c, 0xf1, 0x48, 0xfc, 0x79, + 0x6a, 0xd8, 0xfd, 0xe0, 0xfc, 0x45, 0x59, 0x8f, 0xc6, 0x96, + 0x8d, 0xff, 00, 0x2d, 0x56, 0xbd, 0xe, 0xf3, 0xf6, 0x2d, + 0xf1, 0x44, 0x4c, 0x40, 0xd1, 0x25, 0x6c, 0x77, 0x49, 0x10, + 0xff, 00, 0x26, 0xac, 0x2b, 0xcf, 0xd9, 0x13, 0xc5, 0x96, + 0xec, 0x47, 0xf6, 0x16, 0xa3, 0xc7, 0xfc, 0xf3, 0x89, 0x9b, + 0xf9, 0x56, 0x2f, 0x3, 0x4f, 0xac, 0x24, 0xbe, 0x47, 0x3b, + 0xc9, 0xf1, 0x91, 0xfb, 0x4f, 0xe7, 0x16, 0x60, 0xa7, 0x8a, + 0xed, 0x1f, 0xfe, 0x5a, 0xa7, 0xe7, 0x56, 0x13, 0xc4, 0x56, + 0xcc, 0x3e, 0xfa, 0xfe, 0x75, 0x5e, 0xf7, 0xf6, 0x6c, 0xf1, + 0x2d, 0x96, 0xe2, 0xfa, 0x6e, 0xa7, 0x10, 0x1d, 0xda, 0x16, + 00, 0x7e, 0x95, 0x87, 0x71, 0xf0, 0x6f, 0x5a, 0xb5, 0x62, + 0x18, 0xdc, 0x21, 0x1d, 0x99, 0x6b, 0x9d, 0xe0, 0xa8, 0xf7, + 0x68, 0xe7, 0x78, 0xc, 0x64, 0x7e, 0xda, 0xf9, 0xa3, 0xa9, + 0x5d, 0x66, 0xdd, 0xbf, 0x88, 0x54, 0x83, 0x53, 0x80, 0xff, + 00, 0x10, 0xae, 0x16, 0x4f, 0x86, 0xfa, 0xec, 0x1f, 0x76, + 0x49, 0x4f, 0xd5, 0x6a, 0xbb, 0xf8, 0x43, 0xc4, 0x56, 0xfd, + 0x1d, 0x8f, 0xd4, 0x1a, 0xcf, 0xea, 0x34, 0x9e, 0xd3, 0x32, + 0xfa, 0xbe, 0x35, 0x7f, 0x2b, 0x3d, 0x18, 0x5f, 0x42, 0x7f, + 0x88, 0x53, 0x85, 0xd4, 0x47, 0xa3, 0xd7, 0x98, 0x9d, 0x2b, + 0xc4, 0xb0, 0xff, 00, 0xb, 0x37, 0xe3, 0x4d, 0xdf, 0xe2, + 0x38, 0x3a, 0xc0, 0xc7, 0xf1, 0xa9, 0xfe, 0xcf, 0x8b, 0xda, + 0x62, 0xf6, 0x78, 0xd5, 0xf6, 0x13, 0xf9, 0x9e, 0xa6, 0xb7, + 0x2b, 0xd9, 0xff, 00, 0x5a, 0x91, 0x6e, 0xd8, 0x74, 0x94, + 0xfe, 0x75, 0xe5, 0x3, 0x59, 0xd7, 0xa1, 0xfb, 0xd6, 0x92, + 0x1f, 0xc2, 0x9c, 0x3c, 0x59, 0xaa, 0xc5, 0xf7, 0xed, 0x24, + 0x1f, 0x81, 0xa8, 0x79, 0x6b, 0x7b, 0x34, 0x2e, 0x6c, 0x5c, + 0x77, 0xa4, 0xfe, 0xf3, 0xd6, 0xd3, 0x52, 0xb8, 0x4f, 0xbb, + 0x70, 0xe3, 0xe8, 0xd5, 0x62, 0x3d, 0x7f, 0x50, 0x8f, 0xee, + 0xdd, 0xc8, 0x3f, 0xe0, 0x55, 0xe4, 0xb, 0xe3, 0xbb, 0xb8, + 0xfe, 0xfd, 0xbb, 0x8f, 0xc0, 0xd4, 0xc9, 0xf1, 0xc, 0xaf, + 0xde, 0x8d, 0x87, 0xe7, 0x59, 0xbc, 0xba, 0xa2, 0xda, 0xc3, + 0xfa, 0xd6, 0x26, 0x1b, 0xc2, 0x48, 0xf6, 0x38, 0xbc, 0x63, + 0xac, 0x43, 0x8d, 0x97, 0xb2, 0xc, 0x7b, 0xd5, 0xb8, 0xbe, + 0x22, 0x6b, 0xb0, 0x9e, 0x2f, 0x58, 0xfd, 0x6b, 0xc6, 0x63, + 0xf8, 0x8d, 0x17, 0x7c, 0x8f, 0xc6, 0xac, 0xc7, 0xf1, 0xe, + 0xd8, 0xf5, 0x7a, 0x5f, 0x52, 0xc4, 0x47, 0x6f, 0xcc, 0xb5, + 0x99, 0xd6, 0x8e, 0xfc, 0xcb, 0xef, 0x3d, 0xb2, 0xf, 0x8b, + 0x7e, 0x21, 0x83, 0xa5, 0xd6, 0x7e, 0xb5, 0xa1, 0x6f, 0xf1, + 0xc3, 0xc4, 0x50, 0x11, 0x99, 0xb7, 0x62, 0xbc, 0x36, 0x3f, + 0x1e, 0xda, 0x37, 0xfc, 0xb5, 0x15, 0x66, 0x3f, 0x1a, 0xda, + 0x37, 0xfc, 0xb5, 0x5a, 0x7e, 0xcb, 0x17, 0x1d, 0x9b, 0xfb, + 0xd9, 0xb4, 0x73, 0xba, 0xb1, 0xfb, 0x6d, 0x1e, 0xf9, 0x6f, + 0xfb, 0x43, 0x78, 0x82, 0x10, 0x1, 0x73, 0xf9, 0xd6, 0xa5, + 0xaf, 0xed, 0x2f, 0xac, 0xc5, 0xf7, 0xb2, 0x6b, 0xe7, 0x74, + 0xf1, 0x6d, 0xa3, 0x7f, 0xcb, 0x54, 0xfc, 0xea, 0x74, 0xf1, + 0x25, 0xab, 0xff, 00, 0x1a, 0xfe, 0x75, 0x4a, 0xae, 0x3a, + 0x1b, 0x4e, 0x47, 0x4c, 0x78, 0x86, 0xaa, 0xff, 00, 0x97, + 0xa7, 0xd2, 0xd0, 0x7e, 0xd4, 0xfa, 0x82, 0xe3, 0x7a, 0xb6, + 0x3e, 0x95, 0xab, 0x6b, 0xfb, 0x55, 0xb8, 0xc7, 0x98, 0x9f, + 0x9a, 0xd7, 0xcb, 0x4b, 0xad, 0xdb, 0xb7, 0xf1, 0x8f, 0xce, + 0xa5, 0x5d, 0x56, 0x3, 0xfc, 0x43, 0xf3, 0xab, 0x58, 0xec, + 0x7c, 0x7e, 0xdb, 0x3a, 0xe3, 0xc4, 0x75, 0xff, 00, 0xe7, + 0xe2, 0x3e, 0xb4, 0xb6, 0xfd, 0xaa, 0xad, 0x9c, 0xfc, 0xe8, + 0xa3, 0xfe, 0x3, 0x5a, 0xb6, 0xdf, 0xb4, 0xfe, 0x94, 0xf8, + 0xde, 0x13, 0xf2, 0x22, 0xbe, 0x39, 0x17, 0xf0, 0xb7, 0xf1, + 0xa, 0x78, 0xbb, 0x88, 0xf4, 0x71, 0x5a, 0xac, 0xdb, 0x1f, + 0x1f, 0xb5, 0xf8, 0x1d, 0x91, 0xe2, 0x4a, 0xfd, 0xd3, 0x3e, + 0xd6, 0xb6, 0xfd, 0xa4, 0x34, 0x29, 0xb1, 0xb8, 0xa8, 0xfc, + 0x6b, 0x52, 0xf, 0x8f, 0x5e, 0x1d, 0x94, 0xc, 0xca, 0x6, + 0x7d, 0xd, 0x7c, 0x2e, 0x2e, 0x53, 0xb3, 0xfe, 0xb5, 0x22, + 0xdd, 0x63, 0xa4, 0xa7, 0xf0, 0x35, 0xaa, 0xcf, 0x31, 0xb1, + 0xde, 0xcf, 0xe4, 0x75, 0x47, 0x89, 0x6a, 0xf5, 0x8a, 0x3e, + 0xf5, 0xb7, 0xf8, 0xcb, 0xe1, 0xd9, 0xff, 00, 0xe5, 0xe3, + 0x15, 0xa1, 0x17, 0xc4, 0xed, 0x2, 0x5e, 0x97, 0x80, 0x7d, + 0x6b, 0xf3, 0xf9, 0x2f, 0x65, 0x5f, 0xbb, 0x3b, 0x8f, 0xa3, + 0x54, 0xc9, 0xab, 0xdd, 0xc7, 0xf7, 0x6e, 0xa4, 0x1f, 0xf0, + 0x23, 0x5b, 0xae, 0x20, 0xc4, 0x2d, 0xe0, 0x8e, 0x98, 0xf1, + 0x2c, 0xba, 0xc0, 0xfd, 0x7, 0x8b, 0xc7, 0x3a, 0x2c, 0xdf, + 0x76, 0xf5, 0x3f, 0x1a, 0xb4, 0x9e, 0x28, 0xd2, 0xe4, 0xfb, + 0xb7, 0xb1, 0x9f, 0xc6, 0xbf, 0x3d, 0xa3, 0xf1, 0x2e, 0xa7, + 0x1f, 0xdd, 0xbd, 0x97, 0xfe, 0xfa, 0x35, 0x6a, 0x2f, 0x1b, + 0x6b, 0x30, 0x91, 0xb6, 0xf6, 0x4e, 0x3d, 0x58, 0xd6, 0xcb, + 0x88, 0xa7, 0xd6, 0x9f, 0xe2, 0x74, 0x2e, 0x24, 0x87, 0x58, + 0x1f, 0xa1, 0x11, 0xea, 0xf6, 0x52, 0xfd, 0xdb, 0x98, 0xcf, + 0xfc, 0xa, 0xa6, 0x5b, 0xc8, 0x1b, 0xa4, 0xc8, 0x7e, 0x8c, + 0x2b, 0xf3, 0xfa, 0x1f, 0x89, 0x7a, 0xf4, 0x23, 0x8b, 0xc7, + 0xfc, 0xcd, 0x5e, 0x83, 0xe3, 0x7, 0x88, 0x20, 0xc6, 0x2e, + 0x58, 0xe3, 0xfd, 0xa3, 0x5b, 0xc7, 0x88, 0xa3, 0xd6, 0x9b, + 0x3a, 0x23, 0xc4, 0x58, 0x77, 0xba, 0x67, 0xde, 0xe2, 0x45, + 0x6e, 0x8c, 0xf, 0xd0, 0xd2, 0xe6, 0xbe, 0x18, 0x87, 0xe3, + 0xb7, 0x88, 0x22, 0xc0, 0xf3, 0xf, 0xfd, 0xf4, 0x6b, 0x4e, + 0xdf, 0xf6, 0x8a, 0xd7, 0x21, 0x23, 0x3b, 0x8e, 0x3f, 0xda, + 0x35, 0xba, 0xe2, 0x1a, 0x1d, 0x62, 0xce, 0x88, 0xe7, 0xf8, + 0x47, 0xbb, 0x3e, 0xd5, 0xa2, 0xbe, 0x3e, 0x83, 0xf6, 0x9c, + 0xd5, 0xd0, 0x8d, 0xe1, 0xb1, 0xfe, 0xf1, 0xad, 0x5b, 0x5f, + 0xda, 0x9a, 0xed, 0x71, 0xbd, 0xf, 0x15, 0xbc, 0x73, 0xec, + 0x23, 0xde, 0xeb, 0xe4, 0x74, 0x47, 0x3a, 0xc1, 0xcb, 0xed, + 0x1f, 0x56, 0x51, 0x5f, 0x33, 0xdb, 0x7e, 0xd5, 0x44, 0x91, + 0xe6, 0x20, 0x1f, 0x51, 0x5a, 0xd6, 0xff, 00, 0xb5, 0x35, + 0x91, 0x3, 0x7a, 0xa7, 0xe4, 0x6b, 0xa2, 0x39, 0xd6, 0xa, + 0x5f, 0x6c, 0xe8, 0x8e, 0x69, 0x84, 0x96, 0xd3, 0x47, 0xd0, + 0x54, 0x57, 0x88, 0xdb, 0x7e, 0xd3, 0x5a, 0x4c, 0xa4, 0x6f, + 0x11, 0x8f, 0xc4, 0xd6, 0x9c, 0x1f, 0xb4, 0x56, 0x83, 0x26, + 0x32, 0xf1, 0xe7, 0xd9, 0xeb, 0x78, 0xe6, 0xb8, 0x39, 0x6d, + 0x51, 0x1b, 0xac, 0x76, 0x1e, 0x5b, 0x4d, 0x1e, 0xb7, 0x45, + 0x79, 0xbd, 0xbf, 0xc7, 0x4f, 0xf, 0xcf, 0xff, 00, 0x2d, + 0x94, 0x7f, 0xc0, 0xeb, 0x46, 0x1f, 0x8b, 0xfe, 0x1e, 0x9b, + 0x3, 0xed, 0x40, 0x1f, 0xad, 0x74, 0x47, 0x1b, 0x86, 0x96, + 0xd5, 0x17, 0xde, 0x6c, 0xb1, 0x14, 0x5e, 0xd2, 0x47, 0x6f, + 0x45, 0x72, 0xf0, 0x7c, 0x49, 0xd0, 0x67, 0xe9, 0x7a, 0x83, + 0xea, 0x6a, 0xdc, 0x7e, 0x36, 0xd1, 0x65, 0xfb, 0xb7, 0xf1, + 0x9f, 0xc6, 0xb6, 0x55, 0xe9, 0x3d, 0xa4, 0xbe, 0xf2, 0xd5, + 0x58, 0x3d, 0xa4, 0x8d, 0xda, 0x2b, 0x32, 0x3f, 0x12, 0x69, + 0x92, 0xfd, 0xdb, 0xd8, 0xbf, 0xef, 0xaa, 0x9d, 0x35, 0x7b, + 0x29, 0x3e, 0xed, 0xd4, 0x47, 0xfe, 0x4, 0x2b, 0x45, 0x38, + 0xbd, 0x99, 0x7c, 0xd1, 0xee, 0x5c, 0xa2, 0xa1, 0x5b, 0xb8, + 0x1f, 0xee, 0xca, 0x87, 0xfe, 0x4, 0x2a, 0x41, 0x22, 0x37, + 0x46, 0x53, 0xf4, 0x35, 0x57, 0x45, 0xe, 0xa2, 0x93, 0x39, + 0xa5, 0xa6, 0x1, 0x45, 0x14, 0x50, 0x1, 0x45, 0x14, 0x50, + 0x1, 0x45, 0x14, 0x50, 0x1, 0x45, 0x14, 0x50, 0x1, 0x45, + 0x14, 0x50, 0x1, 0x45, 0x14, 0x50, 0x1, 0x45, 0x14, 0x50, + 0x1, 0x45, 0x14, 0x50, 0x1, 0x45, 0x14, 0x50, 0x1, 0x45, + 0x14, 0x50, 0x1, 0x45, 0x14, 0x50, 0x1, 0x45, 0x14, 0x50, + 0x1, 0x45, 0x14, 0x50, 0x1, 0x48, 0x78, 0x14, 0xb4, 0xc9, + 0x5b, 0x64, 0x4e, 0xde, 0x80, 0x9a, 00, 0xf8, 0xdb, 0xf6, + 0x85, 0xba, 0xf3, 0x75, 0xd9, 0x87, 0xfb, 0x67, 0xf9, 0xd7, + 0x80, 0x78, 0x89, 0xf6, 0x59, 0x4d, 0xfe, 0xe9, 0xaf, 0x68, + 0xf8, 0xe1, 0x73, 0xe6, 0xf8, 0x82, 0x50, 0x4f, 0xf1, 0x93, + 0xfa, 0xd7, 0x84, 0x78, 0xc6, 0xf0, 0x41, 0xa7, 0x4c, 0x72, + 0x7, 0xca, 0x6b, 0xf2, 0xb7, 0xfb, 0xcc, 0x6c, 0xdf, 0x99, + 0xf8, 0xb7, 0x10, 0xce, 0xf5, 0x66, 0x6f, 0x7f, 0xc1, 0x3d, + 0xac, 0x1b, 0x50, 0xfd, 0xab, 0x75, 0x8b, 0xbd, 0xb9, 0x8e, + 0xcb, 0xc3, 0xf7, 0x4, 0x9f, 0x46, 0x79, 0xa1, 0x51, 0xfa, + 0x66, 0xbf, 0x4f, 0x2b, 0xf3, 0x97, 0xfe, 0x9, 0x81, 0x68, + 0x6f, 0xfe, 0x2d, 0x7c, 0x4d, 0xd5, 0xa, 0x9d, 0xb6, 0xfa, + 0x75, 0xa5, 0xb0, 0x6c, 0x71, 0x99, 0x25, 0x91, 0x88, 0xcf, + 0xfd, 0xb3, 0x15, 0xfa, 0x35, 0x5f, 0xa5, 0xe1, 0xd5, 0xa9, + 0xa3, 0xf5, 0xc, 0x9e, 0x1e, 0xcf, 0x1, 0x4a, 0x3e, 0x48, + 0x28, 0xa2, 0x8a, 0xe9, 0x3d, 0x90, 0xa2, 0x8a, 0x28, 00, + 0xa2, 0x8a, 0x28, 00, 0xa2, 0x8a, 0x28, 00, 0xa2, 0x8a, + 0x28, 00, 0xa2, 0x8a, 0x28, 00, 0xa8, 0xe4, 0x82, 0x29, + 0x46, 0x1e, 0x34, 0x71, 0xe8, 0xca, 0xd, 0x49, 0x45, 00, + 0x50, 0x9f, 0x41, 0xd3, 0x2e, 0x46, 0x26, 0xd3, 0xad, 0x25, + 0x1e, 0x8f, 0x2, 0x9f, 0xe6, 0x2b, 0x3e, 0xe3, 0xc0, 0x1e, + 0x19, 0xbb, 0xff, 00, 0x5b, 0xa0, 0x69, 0xad, 0xff, 00, + 0x6e, 0xa8, 0x3f, 0x90, 0xad, 0xfa, 0x2a, 0x1c, 0x20, 0xf7, + 0x46, 0x6e, 0x9c, 0x25, 0xbc, 0x51, 0xc5, 0xdd, 0xfc, 0x19, + 0xf0, 0x55, 0xe9, 0xcc, 0x9e, 0x1e, 0xb4, 0x1f, 0xf5, 0xcc, + 0x14, 0xfe, 0x44, 0x56, 0x45, 0xdf, 0xec, 0xe9, 0xe0, 0x4b, + 0xbc, 0xff, 00, 0xc4, 0xa0, 0xc3, 0x9f, 0xf9, 0xe7, 0x33, + 0x71, 0xf9, 0x93, 0x5e, 0x97, 0x45, 0x62, 0xf0, 0xd4, 0x65, + 0xbc, 0x17, 0xdc, 0x63, 0x2c, 0x26, 0x1e, 0x5b, 0xd3, 0x5f, + 0x72, 0x3c, 0x66, 0xef, 0xf6, 0x51, 0xf0, 0x4d, 0xce, 0x76, + 0x8b, 0xc8, 0x73, 0xfd, 0xd9, 0x10, 0xff, 00, 0x35, 0xac, + 0x9b, 0xaf, 0xd8, 0xeb, 0xc2, 0x93, 0x3, 0xe5, 0xdf, 0x5d, + 0xc6, 0x7f, 0xda, 0x54, 0x6f, 0xe8, 0x2b, 0xdf, 0x28, 0xac, + 0x9e, 0xb, 0xe, 0xfe, 0xc2, 0x30, 0x79, 0x76, 0x11, 0xff, + 00, 0xcb, 0xb4, 0x7c, 0xd5, 0x79, 0xfb, 0x13, 0xe8, 0xd2, + 0xff, 00, 0xa9, 0xd6, 0x9d, 0x7d, 0x9e, 0xd8, 0x1f, 0xfd, + 0x9a, 0xb0, 0xaf, 0x7f, 0x61, 0xa4, 0x6c, 0xf9, 0x1a, 0xbd, + 0xb3, 0xff, 00, 0xd7, 0x48, 0x4a, 0xff, 00, 0x8d, 0x7d, + 0x65, 0x45, 0x66, 0xf2, 0xfc, 0x3b, 0xfb, 0x3f, 0x8b, 0x32, + 0x79, 0x56, 0x11, 0xfd, 0x9f, 0xc5, 0xff, 00, 0x99, 0xf1, + 0x6d, 0xef, 0xec, 0x2f, 0xa9, 0xe0, 0x98, 0xee, 0x34, 0xe9, + 0x7d, 0x83, 0x11, 0xfc, 0xd6, 0xb9, 0xeb, 0xdf, 0xd8, 0x7f, + 0xc4, 0x28, 0xe, 0xcb, 0xb, 0x79, 0x7f, 0xdc, 0x99, 0x3f, + 0xa9, 0x15, 0xf7, 0x9d, 0x15, 0x9b, 0xcb, 0x68, 0xf4, 0x6d, + 0x7c, 0xcc, 0x25, 0x93, 0x61, 0x9e, 0xd7, 0x5f, 0x33, 0xf3, + 0xb6, 0xf3, 0xf6, 0x2d, 0xf1, 0x4c, 0x4a, 0x48, 0xd0, 0xe4, + 0x3f, 0xf5, 0xce, 0x44, 0x6f, 0xe4, 0xd5, 0x87, 0x7d, 0xfb, + 0x22, 0x78, 0xae, 0xd7, 0x27, 0xfb, 0xb, 0x50, 0xff, 00, + 0x80, 0x46, 0xcd, 0xfc, 0xab, 0xf4, 0xba, 0x8a, 0x8f, 0xec, + 0xc8, 0xf4, 0x9b, 0xfc, 0xe, 0x79, 0x64, 0x54, 0x1e, 0xd2, + 0x7f, 0x87, 0xf9, 0x1f, 0x96, 0x37, 0xbf, 0xb3, 0x77, 0x88, + 0xec, 0x98, 0xac, 0x9a, 0x6e, 0xa5, 0xb, 0x7a, 0x34, 0x2c, + 0x3f, 0xa5, 0x62, 0xdd, 0x7c, 0x18, 0xd6, 0xad, 0x1b, 0x69, + 0x17, 0x31, 0x91, 0xd9, 0x97, 0x15, 0xfa, 0xd1, 0x51, 0xbd, + 0xbc, 0x52, 0xe7, 0x7c, 0x48, 0xf9, 0xfe, 0xf2, 0x83, 0x50, + 0xf2, 0xd9, 0x74, 0xa9, 0xf8, 0x7f, 0xc1, 0x39, 0x65, 0xc3, + 0xb4, 0xa5, 0xf6, 0x97, 0xfe, 0x3, 0xff, 00, 0x4, 0xfc, + 0x8c, 0x97, 0xe1, 0xa6, 0xb9, 0x7, 0xdd, 0x92, 0x5f, 0xc5, + 0x4d, 0x57, 0x7f, 0x6, 0xf8, 0x86, 0xe, 0x8e, 0xdc, 0x7a, + 0x82, 0x2b, 0xf5, 0xae, 0x7f, 0xb, 0xe8, 0xd7, 0x24, 0x99, + 0xb4, 0x9b, 0x19, 0x49, 0xea, 0x5e, 0xdd, 0xf, 0xf4, 0xac, + 0xd9, 0xbe, 0x19, 0xf8, 0x4e, 0xe0, 0x93, 0x27, 0x87, 0x74, + 0xd2, 0x4f, 0x53, 0xf6, 0x65, 0x1f, 0xd2, 0xb3, 0x79, 0x75, + 0x6e, 0x93, 0x5f, 0x71, 0xc7, 0x3e, 0x18, 0xa6, 0xff, 00, + 0x97, 0xee, 0x3f, 0x28, 0xe, 0x8f, 0xe2, 0x38, 0x3d, 0x4f, + 0xe2, 0x69, 0x9f, 0xf1, 0x51, 0xc1, 0xd6, 0x26, 0x6f, 0xc6, + 0xbf, 0x54, 0x67, 0xf8, 0x29, 0xe0, 0x8b, 0x90, 0x43, 0xf8, + 0x76, 0xd0, 0x67, 0xba, 0xee, 0x5f, 0xe4, 0x6b, 0x1e, 0xef, + 0xf6, 0x6e, 0xf0, 0xd, 0xd0, 0xe3, 0x48, 0x68, 0x4f, 0xac, + 0x73, 0xbf, 0xf5, 0x26, 0xb2, 0x79, 0x75, 0x7f, 0xee, 0xbf, + 0xeb, 0xd0, 0xe4, 0x9f, 0xa, 0x45, 0xed, 0x18, 0xfd, 0xef, + 0xfc, 0x8f, 0xcc, 0x7f, 0xed, 0x6d, 0x7a, 0x1f, 0xbd, 0x6c, + 0xe6, 0x94, 0x78, 0xa7, 0x56, 0x8b, 0xef, 0xda, 0xc9, 0xff, + 00, 0x7c, 0x9a, 0xfd, 0x1f, 0xbc, 0xfd, 0x93, 0xbc, 0xf, + 0x73, 0xfe, 0xad, 0x2f, 0x20, 0xff, 00, 0x76, 0x45, 0x3f, + 0xcd, 0x6b, 0x12, 0xf7, 0xf6, 0x35, 0xf0, 0xbc, 0xf9, 0xf2, + 0x35, 0xb, 0x98, 0xbf, 0xdf, 0x8d, 0x5b, 0xf9, 0x62, 0xb1, + 0x96, 0x5f, 0x5b, 0xf9, 0x13, 0x38, 0xe5, 0xc2, 0x8d, 0x6d, + 0x1f, 0xba, 0x47, 0xe7, 0xf0, 0xf1, 0xcd, 0xe4, 0x63, 0xe7, + 0xb7, 0x71, 0xf5, 0x6, 0xa6, 0x4f, 0x88, 0x4e, 0xbf, 0x7a, + 0x32, 0x3f, 0x3a, 0xfb, 0x82, 0xef, 0xf6, 0x24, 0xd3, 0x64, + 0x3f, 0xb9, 0xd6, 0x94, 0xf, 0xf6, 0xed, 0x7f, 0xfb, 0x2a, + 0xc5, 0xbd, 0xfd, 0x86, 0x4b, 0x67, 0xc9, 0xd5, 0xac, 0xe4, + 0xf4, 0xf3, 0x22, 0x65, 0xff, 00, 0x1a, 0xc1, 0xe0, 0x2a, + 0x75, 0xa3, 0xf8, 0xaf, 0xf3, 0x39, 0x65, 0xc3, 0x15, 0x56, + 0xd1, 0x97, 0xde, 0xbf, 0xcc, 0xf9, 0x6, 0x3f, 0x88, 0xa9, + 0xfc, 0x40, 0x8a, 0xb5, 0x1f, 0xc4, 0x4b, 0x73, 0xd5, 0xb1, + 0xf8, 0xd7, 0xd2, 0xb7, 0xbf, 0xb0, 0xae, 0xaa, 0x1, 0xf2, + 0xa7, 0xd3, 0x26, 0xff, 00, 0x81, 0x11, 0xfc, 0xd6, 0xb9, + 0xfb, 0xef, 0xd8, 0x77, 0xc4, 0x71, 0x3, 0xb2, 0xc2, 0xd6, + 0x6f, 0xfa, 0xe7, 0x32, 0xff, 00, 0x52, 0x2b, 0x9, 0x60, + 0x7b, 0xd2, 0x67, 0x3c, 0xb8, 0x7b, 0x13, 0x1d, 0x9c, 0xfe, + 0xeb, 0x9e, 0x27, 0x1f, 0x8f, 0xad, 0x5b, 0x1f, 0xbc, 0xc5, + 0x59, 0x4f, 0x1b, 0x5a, 0xb7, 0xfc, 0xb5, 0x5f, 0xc6, 0xbd, + 0xe, 0xff, 00, 0xf6, 0x31, 0xf1, 0x4d, 0xbe, 0x4f, 0xf6, + 0x1c, 0x8c, 0x3d, 0x63, 0x60, 0xdf, 0xc8, 0xd7, 0x3f, 0x7b, + 0xfb, 0x28, 0xf8, 0x9a, 0xd4, 0x9c, 0xe8, 0x5a, 0x8a, 0xfb, + 0xac, 0xe, 0x7f, 0xa5, 0x61, 0x2c, 0x15, 0x35, 0xbc, 0x1a, + 0xf9, 0x1c, 0xd2, 0xc9, 0xb1, 0x70, 0xfb, 0x6f, 0xe7, 0x16, + 0x62, 0x27, 0x8b, 0xed, 0x5b, 0xfe, 0x5a, 0xa7, 0xe7, 0x53, + 0xa7, 0x89, 0xad, 0x9f, 0xa4, 0x89, 0xf9, 0xd5, 0x7b, 0xcf, + 0xd9, 0xd7, 0xc4, 0x36, 0x79, 0x2f, 0xa7, 0xea, 0x11, 0x1, + 0xfd, 0xe8, 0x58, 0x7f, 0x4a, 0xc6, 0xb8, 0xf8, 0x3b, 0xac, + 0xdb, 0x67, 0xfe, 0x3e, 0x13, 0x1f, 0xde, 0x43, 0x58, 0x3c, + 0x1d, 0xf, 0x34, 0x60, 0xf2, 0xfc, 0x64, 0x7e, 0xda, 0xf9, + 0xa3, 0xa8, 0x5d, 0x7a, 0xdd, 0xbf, 0x8d, 0x7f, 0x3a, 0x95, + 0x75, 0x78, 0xf, 0xf1, 0xa, 0xe1, 0x24, 0xf8, 0x6f, 0xad, + 0xc3, 0x9d, 0xb2, 0xc9, 0xf8, 0xa1, 0xaa, 0xef, 0xe0, 0xfd, + 0x7e, 0xe, 0x92, 0x31, 0xfc, 0xd, 0x47, 0xd4, 0xa8, 0xbd, + 0xa4, 0x67, 0xf5, 0x5c, 0x6a, 0xeb, 0x16, 0x7a, 0x38, 0xd4, + 0xa1, 0x6f, 0xe2, 0x14, 0xe1, 0x7d, 0x9, 0xfe, 0x31, 0x5e, + 0x62, 0xda, 0x47, 0x88, 0xa0, 0xe8, 0x49, 0xfc, 0x4d, 0x34, + 0xff, 00, 0xc2, 0x43, 0x7, 0x58, 0xd9, 0xbf, 0x1a, 0x87, + 0x97, 0xc7, 0xa4, 0x89, 0xf6, 0x58, 0xe5, 0xf6, 0x13, 0xf9, + 0x9e, 0xa6, 0x2e, 0xa3, 0x3f, 0xc4, 0x29, 0xc2, 0xe1, 0x4f, + 0x47, 0xfd, 0x6b, 0xca, 0x7f, 0xb5, 0xb5, 0xd8, 0x7e, 0xf5, + 0xb4, 0x87, 0xf0, 0xa7, 0xf, 0x14, 0xea, 0xb1, 0x7d, 0xeb, + 0x69, 0x3f, 0xef, 0x9a, 0x97, 0x97, 0x3e, 0x92, 0x44, 0xff, + 00, 0xb5, 0xc7, 0x7a, 0x47, 0xab, 0x8b, 0x93, 0xda, 0x53, + 0xf9, 0xd4, 0x89, 0x7d, 0x32, 0xfd, 0xd9, 0xd8, 0x7f, 0xc0, + 0xab, 0xc9, 0xd7, 0xc7, 0x17, 0x91, 0xfd, 0xfb, 0x77, 0x1f, + 0x81, 0xa9, 0x93, 0xe2, 0x13, 0xaf, 0xde, 0x8d, 0x85, 0x64, + 0xf2, 0xd9, 0xf4, 0xb0, 0x7b, 0x7c, 0x44, 0x77, 0xa7, 0x23, + 0xd6, 0x53, 0x58, 0xbd, 0x4f, 0xbb, 0x75, 0x28, 0xff, 00, + 0x81, 0x1a, 0xb1, 0x1f, 0x89, 0xb5, 0x38, 0xbe, 0xed, 0xe4, + 0xa3, 0xfe, 0x4, 0x6b, 0xc9, 0xa3, 0xf8, 0x88, 0x9d, 0xc3, + 0xf, 0xc6, 0xac, 0xc7, 0xf1, 0xa, 0x3, 0xfc, 0x44, 0x54, + 0x7f, 0x67, 0xd6, 0x5b, 0x21, 0xac, 0xc2, 0xac, 0x77, 0x52, + 0x5f, 0x79, 0xeb, 0x71, 0xf8, 0xe3, 0x5a, 0x8b, 0xa5, 0xf4, + 0x9f, 0xf7, 0xd5, 0x5c, 0x83, 0xe2, 0x6e, 0xbd, 0x6, 0x31, + 0x74, 0xc7, 0xea, 0x4d, 0x79, 0x14, 0x7e, 0x3e, 0xb6, 0x6e, + 0xaf, 0x8a, 0xb3, 0x1f, 0x8d, 0xad, 0x5b, 0xfe, 0x5a, 0x8a, + 0x5f, 0x55, 0xc4, 0x47, 0x6b, 0xfd, 0xec, 0xd5, 0x66, 0xf3, + 0x8f, 0xdb, 0x92, 0x3d, 0x8e, 0x1f, 0x8c, 0x3e, 0x20, 0x8b, + 0x1f, 0xe9, 0x4, 0xe3, 0xdc, 0xd6, 0x8d, 0xbf, 0xc7, 0x7d, + 0x7a, 0x1c, 0x7c, 0xe4, 0xff, 00, 0xc0, 0x8d, 0x78, 0x9a, + 0x78, 0xbe, 0xd5, 0xbf, 0xe5, 0xaa, 0xfe, 0x75, 0x3a, 0x78, + 0x9e, 0xd9, 0xff, 00, 0xe5, 0xa2, 0xfe, 0x74, 0x72, 0xe2, + 0xe1, 0xb3, 0x7f, 0x7b, 0x3a, 0x23, 0x9e, 0x54, 0x5f, 0xf2, + 0xf5, 0x9e, 0xef, 0x6f, 0xfb, 0x45, 0x6b, 0x71, 0x63, 0x73, + 0x31, 0xff, 00, 0x81, 0x1a, 0xd6, 0xb6, 0xfd, 0xa6, 0xf5, + 0x48, 0xb1, 0xb8, 0x39, 0xff, 00, 0x81, 0x57, 0xcf, 0x29, + 0xaf, 0xdb, 0xb7, 0xf1, 0xaf, 0xe7, 0x52, 0xae, 0xb1, 0x3, + 0x7f, 0x10, 0xfc, 0xea, 0xd6, 0x23, 0x1b, 0xd, 0xa6, 0xce, + 0xb8, 0x71, 0x5, 0x65, 0xb5, 0x53, 0xe9, 0x4b, 0x6f, 0xda, + 0x92, 0xec, 0x7f, 0xac, 0xdd, 0x5a, 0xd6, 0xdf, 0xb5, 0x42, + 0xf1, 0xbd, 0x41, 0xfa, 0x8a, 0xf9, 0x65, 0x75, 0x38, 0x4f, + 0xf1, 0xf, 0xce, 0x9e, 0x2f, 0xa1, 0x6f, 0xe2, 0x15, 0xa2, + 0xcc, 0x71, 0xf1, 0xfb, 0x6c, 0xeb, 0x8f, 0x11, 0x62, 0x3f, + 0x9d, 0x1f, 0x5b, 0xdb, 0x7e, 0xd4, 0x56, 0x6f, 0x8f, 0x30, + 0x20, 0xfc, 0x2b, 0x56, 0xf, 0xda, 0x63, 0x49, 0x93, 0x19, + 0xf2, 0xfe, 0xb9, 0x22, 0xbe, 0x35, 0x17, 0x31, 0x1f, 0xe2, + 0x14, 0xf1, 0x3a, 0x1e, 0x8f, 0xfa, 0xd6, 0xcb, 0x38, 0xc7, + 0x47, 0xed, 0x7e, 0x7, 0x5c, 0x78, 0x8f, 0x11, 0xe4, 0xcf, + 0xb6, 0xad, 0xff, 00, 0x68, 0x6d, 0xe, 0x5c, 0x6e, 0x78, + 0xc7, 0xfc, 0xa, 0xb4, 0xa0, 0xf8, 0xe7, 0xe1, 0xf9, 0xb1, + 0x89, 0x57, 0xfe, 0xfa, 0xaf, 0x85, 0x44, 0xe3, 0xb3, 0xfe, + 0xb4, 0xf5, 0xba, 0x91, 0x7a, 0x4a, 0xc3, 0xe8, 0xd5, 0xb2, + 0xcf, 0x71, 0x8b, 0x74, 0x8e, 0xa8, 0xf1, 0x25, 0x5e, 0xb1, + 0x3e, 0xf8, 0xb7, 0xf8, 0xb9, 0xa0, 0x4c, 0x1, 0xfb, 0x48, + 0x1f, 0x8d, 0x5d, 0x8b, 0xe2, 0x4e, 0x83, 0x37, 0xdd, 0xbc, + 0x5a, 0xfc, 0xff, 00, 0x5d, 0x46, 0xe5, 0x7a, 0x5c, 0x3f, + 0xfd, 0xf5, 0x53, 0xc7, 0xae, 0xea, 0x11, 0xfd, 0xdb, 0xb9, + 0x7, 0xd1, 0xab, 0x75, 0xc4, 0x35, 0xd6, 0xf0, 0x47, 0x44, + 0x78, 0x91, 0xf5, 0x81, 0xfa, 0xd, 0x1f, 0x8d, 0x74, 0x69, + 0x7a, 0x5f, 0x46, 0x3e, 0xa6, 0xac, 0xc7, 0xe2, 0x5d, 0x32, + 0x5f, 0xbb, 0x7b, 0x11, 0xfc, 0x6b, 0xf3, 0xe5, 0x3c, 0x5b, + 0xab, 0x47, 0x8c, 0x5e, 0xcb, 0xff, 00, 0x7d, 0x55, 0xb8, + 0x7c, 0x7f, 0xad, 0xc3, 0xf7, 0x6f, 0x5f, 0xf1, 0x35, 0xb2, + 0xe2, 0x29, 0x7d, 0xaa, 0x7f, 0x89, 0xd1, 0x1e, 0x24, 0xa6, + 0xf7, 0x89, 0xfa, 0x6, 0x9a, 0xb5, 0x9b, 0xfd, 0xdb, 0xa8, + 0x8f, 0xfc, 0x8, 0x54, 0xa9, 0x79, 0x3, 0xfd, 0xd9, 0x91, + 0xbe, 0x8c, 0x2b, 0xe0, 0x48, 0x7e, 0x29, 0xeb, 0xf1, 0x1f, + 0xf8, 0xfb, 0x73, 0xf8, 0xd6, 0x84, 0x1f, 0x1a, 0x7c, 0x41, + 0x7, 0xfc, 0xb7, 0x27, 0xf1, 0xad, 0xe3, 0xc4, 0x50, 0xeb, + 0x4d, 0xfe, 0x7, 0x44, 0x78, 0x87, 0xe, 0xf7, 0x4c, 0xfb, + 0xbc, 0x3a, 0x9e, 0x8c, 0xf, 0xe3, 0x4b, 0x90, 0x7b, 0xd7, + 0xc3, 0xf6, 0xff, 00, 0x1f, 0x35, 0xc8, 0xb1, 0xba, 0x47, + 0x6f, 0xf8, 0x15, 0x6a, 0x5b, 0xfe, 0xd2, 0x1a, 0xc4, 0x3d, + 0x4b, 0xff, 00, 0xdf, 0x55, 0xd1, 0x1e, 0x21, 0xc3, 0xbd, + 0xe2, 0xd1, 0xd1, 0x1c, 0xfb, 0x8, 0xfa, 0x9f, 0x66, 0xd1, + 0x5f, 0x22, 0xdb, 0x7e, 0xd3, 0xba, 0x8a, 0xe3, 0xcc, 0x32, + 0x1f, 0x6c, 0xd6, 0xad, 0xbf, 0xed, 0x4d, 0x38, 0xc6, 0xe0, + 0xdf, 0x8e, 0x2b, 0x68, 0xe7, 0xd8, 0x37, 0xbb, 0x6b, 0xe4, + 0x6f, 0x1c, 0xe7, 0x7, 0x2f, 0xb4, 0x7d, 0x4b, 0x45, 0x7c, + 0xdf, 0x6b, 0xfb, 0x52, 0x46, 0x71, 0xe6, 0x7e, 0xa2, 0xb5, + 0x2d, 0xff, 00, 0x69, 0xfb, 0x17, 0xc0, 0x65, 0x5f, 0xa9, + 0xad, 0xe3, 0x9d, 0x60, 0xa5, 0xf6, 0xce, 0x88, 0xe6, 0x78, + 0x59, 0x6d, 0x33, 0xdf, 0x28, 0xaf, 0x18, 0xb7, 0xfd, 0xa4, + 0x74, 0x87, 0xc6, 0xf3, 0x18, 0xff, 00, 0x81, 0x56, 0x9d, + 0xbf, 0xed, 0x3, 0xa1, 0xcd, 0x8e, 0x57, 0xfe, 0xfb, 0xae, + 0x88, 0xe6, 0x78, 0x39, 0x6d, 0x51, 0x1b, 0xac, 0x6e, 0x1e, + 0x5b, 0x4d, 0x1e, 0xa9, 0x45, 0x79, 0xec, 0x1f, 0x1a, 0xf4, + 0x9, 0x40, 0xcc, 0xa0, 0x7f, 0xc0, 0x85, 0x5f, 0x83, 0xe2, + 0xc6, 0x83, 0x39, 0xe2, 0xe3, 0x1f, 0x88, 0xae, 0x85, 0x8c, + 0xc3, 0xcb, 0x69, 0xa3, 0x55, 0x88, 0xa4, 0xf6, 0x92, 0x3b, + 0x3a, 0x2b, 0x9a, 0x8f, 0xe2, 0x16, 0x87, 0x27, 0xfc, 0xbe, + 0x28, 0xfc, 0x6a, 0xdc, 0x5e, 0x32, 0xd2, 0x26, 0x3f, 0x2d, + 0xec, 0x7f, 0x9d, 0x6c, 0xab, 0x52, 0x7b, 0x49, 0x1a, 0x2a, + 0x90, 0x7d, 0x4d, 0xaa, 0x2b, 0x39, 0x3c, 0x41, 0xa7, 0x3f, + 0x4b, 0xc8, 0xbf, 0xef, 0xaa, 0x9d, 0x35, 0x4b, 0x49, 0x3e, + 0xed, 0xcc, 0x67, 0xfe, 0x4, 0x2a, 0xd4, 0xe2, 0xf6, 0x65, + 0x73, 0x27, 0xd4, 0xb5, 0x55, 0xb5, 0x27, 0xf2, 0xac, 0x2e, + 0x1b, 0xd1, 0x9, 0xfd, 0x2a, 0x41, 0x73, 0xb, 0x74, 0x95, + 0xf, 0xfc, 0x8, 0x56, 0x4f, 0x8b, 0xb5, 0x58, 0x34, 0xef, + 0xf, 0x5e, 0xcd, 0x24, 0xaa, 0x2, 0xc6, 0x7f, 0x88, 0x52, + 0x9c, 0x92, 0x8b, 0x62, 0x94, 0x92, 0x8b, 0x67, 0xc3, 0xff, + 00, 0x18, 0xef, 0x47, 0xf6, 0xe4, 0xc4, 0x9f, 0xe2, 0x3f, + 0xce, 0xbe, 0x6a, 0xf8, 0x9d, 0xe2, 0x25, 0x8a, 0xdd, 0xe2, + 0x57, 0xc1, 0xc1, 0xef, 0x5e, 0xa7, 0xf1, 0xaf, 0xc6, 0xf0, + 0x7f, 0x69, 0x5c, 0x4a, 0xae, 0x32, 0x58, 0xe0, 0x66, 0xbe, + 0x67, 0xbe, 0x87, 0x53, 0xf8, 0x83, 0xe2, 0x5b, 0x1d, 0x13, + 0x4b, 0x89, 0xee, 0x75, 0x2d, 0x4a, 0xe1, 0x6d, 0xad, 0xe2, + 0x5e, 0x4b, 0x33, 0x1c, 0xa, 0xf8, 0x3c, 0xbf, 0xc, 0xe5, + 0x39, 0x56, 0x7d, 0x5b, 0xb1, 0xf8, 0x9d, 0x78, 0x4b, 0x33, + 0xcc, 0xb9, 0x21, 0xf0, 0xa6, 0x7e, 0x80, 0x7f, 0xc1, 0x2d, + 0xbc, 0x19, 0x36, 0x97, 0xf0, 0xa3, 0xc5, 0x3e, 0x28, 0xb8, + 0x8c, 0xab, 0x6b, 0xda, 0xb6, 0xd8, 0x58, 0xff, 00, 0x14, + 0x30, 0x26, 0xc0, 0x7f, 0xef, 0xb6, 0x93, 0xf2, 0xaf, 0xb5, + 0x6b, 0x88, 0xf8, 0x27, 0xf0, 0xda, 0xdf, 0xe1, 0xf, 0xc2, + 0x9f, 0xc, 0xf8, 0x42, 0xdc, 0xab, 0x8d, 0x2e, 0xcd, 0x22, + 0x92, 0x45, 0x18, 0xf3, 0x25, 0x3f, 0x34, 0x8d, 0xf8, 0xb1, + 0x63, 0x5d, 0xbd, 0x7d, 0xec, 0x23, 0xcb, 0x14, 0x8f, 0xda, + 0x68, 0xc3, 0xd9, 0x53, 0x8c, 0x3b, 0x20, 0xa2, 0x8a, 0x2a, + 0xcd, 0x82, 0x8a, 0x28, 0xa0, 0x2, 0x8a, 0x28, 0xa0, 0x2, + 0x8a, 0x28, 0xa0, 0x2, 0x8a, 0x28, 0xa0, 0x2, 0x8a, 0x28, + 0xa0, 0x2, 0x8a, 0x28, 0xa0, 0x2, 0x8a, 0x28, 0xa0, 0x2, + 0x8a, 0x28, 0xa0, 0x2, 0x8a, 0x28, 0xa0, 0x2, 0x8a, 0x28, + 0xa0, 0x2, 0x8a, 0x28, 0xa0, 0x2, 0x8a, 0x28, 0xa0, 0x2, + 0x8a, 0x28, 0xa0, 0x2, 0x8a, 0x28, 0xa0, 0x2, 0x8a, 0x28, + 0xa0, 0x2, 0x8a, 0x28, 0xa0, 0x2, 0x8a, 0x28, 0xa0, 0x2, + 0x8a, 0x28, 0xa0, 0x2, 0x8a, 0x28, 0xa0, 0x2, 0xa3, 0x92, + 0xde, 0x29, 0x86, 0x24, 0x89, 0x1c, 0x7f, 0xb4, 0xa0, 0xd4, + 0x94, 0x51, 0xb8, 0x19, 0x97, 0x3e, 0x19, 0xd1, 0xef, 0x41, + 0x17, 0x1a, 0x55, 0x94, 0xc0, 0xf6, 0x92, 0xdd, 0xf, 0xf3, + 0x15, 0x97, 0x75, 0xf0, 0xcb, 0xc2, 0x77, 0x83, 0x12, 0xf8, + 0x7b, 0x4f, 0x3f, 0xee, 0xc0, 0xab, 0xfc, 0xb1, 0x5d, 0x3d, + 0x15, 0x9b, 0xa7, 0x9, 0x6f, 0x14, 0x64, 0xe9, 0x53, 0x97, + 0xc5, 0x14, 0xfe, 0x47, 0x5, 0x75, 0xf0, 0x2b, 0xc0, 0xd7, + 0x9f, 0x7f, 0x40, 0x85, 0x7f, 0xdc, 0x91, 0xd7, 0xf9, 0x35, + 0x64, 0xdc, 0x7e, 0xcd, 0x1e, 0x2, 0xb8, 0x24, 0xff, 00, + 0x65, 0xcb, 0x1e, 0x7b, 0x24, 0xed, 0xfd, 0x73, 0x5e, 0xa7, + 0x45, 0x62, 0xf0, 0xb4, 0x1e, 0xf0, 0x5f, 0x71, 0x83, 0xc1, + 0xe1, 0xa5, 0xbd, 0x35, 0xf7, 0x23, 0xc5, 0xae, 0x7f, 0x64, + 0xbf, 0x3, 0x5c, 0x64, 0xa8, 0xbe, 0x8b, 0x3d, 0x2, 0xca, + 0xa4, 0xf, 0xcd, 0x6b, 0x16, 0xeb, 0xf6, 0x32, 0xf0, 0xb4, + 0xa1, 0xbc, 0xad, 0x46, 0xee, 0x33, 0xdb, 0x72, 0x29, 0xff, + 00, 0xa, 0xfa, 0xe, 0x8a, 0xcd, 0xe0, 0x70, 0xef, 0xec, + 0x19, 0x3c, 0xbb, 0x8, 0xff, 00, 0xe5, 0xda, 0x3e, 0x61, + 0xbb, 0xfd, 0x88, 0xb4, 0xe7, 0x53, 0xe4, 0xeb, 0x99, 0x3d, + 0x83, 0xdb, 0x60, 0x7f, 0xe8, 0x55, 0xcf, 0xdf, 0x7e, 0xc3, + 0x77, 0x27, 0xfd, 0x46, 0xa5, 0x63, 0x2f, 0xfb, 0xe1, 0x97, + 0xff, 00, 0x65, 0x35, 0xf5, 0xf5, 0x15, 0x93, 0xcb, 0xb0, + 0xef, 0x64, 0xd7, 0xcd, 0x98, 0xbc, 0xab, 0x8, 0xfe, 0xcd, + 0xbe, 0x6c, 0xf8, 0x92, 0xf7, 0xf6, 0x18, 0xd6, 0xb9, 0xf2, + 0xdb, 0x4e, 0x97, 0xfd, 0xd9, 0x48, 0xfe, 0x6a, 0x2b, 0x6, + 0xfb, 0xf6, 0x1e, 0xf1, 0x2c, 0x64, 0xec, 0xd3, 0xad, 0xa6, + 0xf7, 0x4b, 0x84, 0xfe, 0xa4, 0x57, 0xdf, 0x34, 0x54, 0x3c, + 0xb2, 0x8f, 0x46, 0xfe, 0xf3, 0x7, 0x93, 0x61, 0x9f, 0x57, + 0xf7, 0xff, 00, 0xc0, 0x3f, 0x39, 0xaf, 0x7f, 0x63, 0x1f, + 0x15, 0xdb, 0x92, 0x3f, 0xb0, 0x65, 0x6f, 0xfa, 0xe7, 0x22, + 0xb7, 0xf2, 0x26, 0xb0, 0x2f, 0x7f, 0x65, 0xf, 0x14, 0x5a, + 0x12, 0xe, 0x83, 0xa8, 0xae, 0x3f, 0xbb, 0x13, 0x37, 0xf2, + 0x15, 0xfa, 0x71, 0x45, 0x43, 0xcb, 0x23, 0xd2, 0x6c, 0xc2, + 0x59, 0x15, 0x7, 0xb4, 0x9f, 0xe1, 0xfe, 0x47, 0xe5, 0x3d, + 0xef, 0xec, 0xfd, 0xad, 0xd9, 0x13, 0xe6, 0x59, 0x5e, 0xc3, + 0xfe, 0xfa, 0x11, 0xfc, 0xc5, 0x64, 0x4f, 0xf0, 0x8f, 0x56, + 0xb7, 0x24, 0x3, 0x32, 0xff, 00, 0xbc, 0x2b, 0xf5, 0xb8, + 0xa8, 0x3d, 0x40, 0x35, 0xc, 0x96, 0x16, 0xd3, 0xc, 0x49, + 0x6f, 0x14, 0x83, 0xfd, 0xa4, 0x6, 0xb3, 0x79, 0x6c, 0xfa, + 0x54, 0xfc, 0x3f, 0xe0, 0x9c, 0x92, 0xe1, 0xda, 0x72, 0xfb, + 0x4b, 0xff, 00, 0x1, 0xff, 00, 0x82, 0x7e, 0x45, 0xc9, + 0xf0, 0xeb, 0x5a, 0x83, 0xa4, 0x8f, 0xf8, 0xa9, 0xaa, 0xcf, + 0xe1, 0x1d, 0x7e, 0x1e, 0x8f, 0xf9, 0xe4, 0x57, 0xeb, 0x7c, + 0xfe, 0x15, 0xd1, 0x6e, 0xbf, 0xd7, 0x69, 0x16, 0x32, 0xff, + 00, 0xbf, 0x6c, 0x87, 0xfa, 0x56, 0x65, 0xcf, 0xc3, 0xf, + 0x9, 0x5d, 0xff, 00, 0xad, 0xf0, 0xee, 0x9c, 0x7d, 0xc5, + 0xba, 0xaf, 0xf2, 0xa8, 0x79, 0x75, 0x6e, 0x93, 0x4f, 0xe4, + 0x72, 0x4f, 0x86, 0x29, 0xbd, 0xb9, 0x7e, 0xe3, 0xf2, 0x7c, + 0xe9, 0x3e, 0x22, 0x83, 0xa7, 0x3f, 0xf0, 0x23, 0x4d, 0xff, + 00, 0x8a, 0x8a, 0x1f, 0xf9, 0x66, 0x5b, 0x1e, 0xf5, 0xfa, + 0x9b, 0x75, 0xf0, 0x2b, 0xc0, 0xb7, 0x79, 0xdf, 0xe1, 0xeb, + 0x75, 0xcf, 0xfc, 0xf3, 0x77, 0x5f, 0xe4, 0x6b, 0x26, 0xe7, + 0xf6, 0x67, 0xf0, 0x5, 0xc0, 0x23, 0xfb, 0x2a, 0x48, 0xb3, + 0xdd, 0x27, 0x6f, 0xeb, 0x9a, 0xc9, 0xe5, 0xf5, 0xff, 00, + 0xba, 0xff, 00, 0xaf, 0x43, 0x8e, 0x7c, 0x29, 0x17, 0xf6, + 0x63, 0xf7, 0xbf, 0xf2, 0x3f, 0x32, 0x3f, 0xb5, 0xb5, 0xc8, + 0x4f, 0xcd, 0x6e, 0xe7, 0xf0, 0xcd, 0x28, 0xf1, 0x46, 0xab, + 0x17, 0xdf, 0xb7, 0x7f, 0xfb, 0xe6, 0xbf, 0x48, 0x2e, 0xff, + 00, 0x64, 0xbf, 0x2, 0xdc, 0x8f, 0x91, 0x2f, 0x61, 0xff, + 00, 0x76, 0x55, 0x3f, 0xcd, 0x6b, 0x1e, 0xf3, 0xf6, 0x33, + 0xf0, 0xa4, 0xc3, 0xf7, 0x1a, 0x85, 0xe4, 0x47, 0xfd, 0xb5, + 0x56, 0xff, 00, 0xa, 0xc9, 0xe0, 0x2b, 0x7f, 0x22, 0x67, + 0x24, 0xb8, 0x51, 0xad, 0xa1, 0xf7, 0x48, 0xfc, 0xfa, 0x5f, + 0x1c, 0x5d, 0xc7, 0xf7, 0xe1, 0x61, 0xff, 00, 0x1, 0x35, + 0x32, 0x7c, 0x41, 0x71, 0xf7, 0x90, 0x8f, 0xce, 0xbe, 0xe2, + 0xbd, 0xfd, 0x88, 0x74, 0xc9, 0x3f, 0xe3, 0xdf, 0x5b, 0xc0, + 0xff, 00, 0xa6, 0x96, 0xdf, 0xe0, 0xd5, 0x81, 0x79, 0xfb, + 0xc, 0x4e, 0xcc, 0x7c, 0x9d, 0x52, 0xc5, 0xd7, 0xb6, 0xf5, + 0x65, 0x3f, 0xfa, 0x9, 0xac, 0x1e, 0x2, 0xa7, 0x5a, 0x5f, + 0x91, 0xcb, 0x2e, 0x17, 0xab, 0x1d, 0xa3, 0x2f, 0xbd, 0x7f, + 0x99, 0xf2, 0x24, 0x7f, 0x11, 0x13, 0xbe, 0x6a, 0xd4, 0x7f, + 0x10, 0xa0, 0x38, 0xcb, 0x11, 0x5f, 0x4a, 0x5d, 0xfe, 0xc2, + 0xfa, 0xcf, 0x3e, 0x5b, 0xe9, 0xb2, 0xe, 0xd8, 0x90, 0x8f, + 0xe6, 0xb5, 0x83, 0x79, 0xfb, 0xe, 0xf8, 0x99, 0x41, 0x29, + 0xa7, 0xdb, 0x49, 0xfe, 0xe5, 0xc2, 0xf, 0xeb, 0x58, 0x3c, + 0xf, 0x7a, 0x4c, 0xe6, 0x97, 0xe, 0xe2, 0x23, 0xb7, 0x3f, + 0xdd, 0x73, 0xc4, 0xa3, 0xf1, 0xed, 0xb3, 0x7f, 0xcb, 0x4f, + 0xd2, 0xac, 0xc7, 0xe3, 0x7b, 0x66, 0xff, 00, 0x96, 0xa2, + 0xbd, 0x16, 0xf7, 0xf6, 0x2e, 0xf1, 0x64, 0xa, 0xcd, 0xfd, + 0x83, 0x23, 0x1, 0xff, 00, 0x3c, 0xe5, 0x56, 0xfd, 0x3, + 0x57, 0x3f, 0x7d, 0xfb, 0x28, 0x78, 0xa6, 0xd0, 0x16, 0x7d, + 0x3, 0x51, 0x50, 0x3b, 0xac, 0x4c, 0x7f, 0xa5, 0x60, 0xf0, + 0x54, 0xd6, 0xf0, 0x6b, 0xe4, 0x73, 0xcb, 0x25, 0xc5, 0xc3, + 0xed, 0xc9, 0x7a, 0xa6, 0x61, 0x27, 0x8c, 0x2d, 0x5b, 0xfe, + 0x5a, 0xad, 0x58, 0x4f, 0x14, 0x5b, 0x3f, 0xfc, 0xb4, 0x5f, + 0xce, 0xaa, 0x5f, 0x7e, 0xcf, 0xda, 0xe5, 0x8e, 0x7c, 0xdb, + 0x1b, 0xf8, 0xf, 0xfb, 0x71, 0xb0, 0xfe, 0x62, 0xb2, 0x27, + 0xf8, 0x47, 0xaa, 0xdb, 0xe7, 0x99, 0xd7, 0xea, 0xb5, 0x83, + 0xc2, 0x50, 0xf4, 0x39, 0xde, 0x5f, 0x8b, 0x8f, 0xfc, 0xbc, + 0x5f, 0x34, 0x75, 0x2b, 0xaf, 0xdb, 0xb7, 0xf1, 0x8f, 0xce, + 0xa5, 0x5d, 0x62, 0x16, 0xee, 0x2b, 0x83, 0x93, 0xe1, 0xd6, + 0xb3, 0xf, 0xdd, 0x95, 0xc7, 0xd5, 0x6a, 0xbb, 0xf8, 0x3f, + 0x5e, 0x83, 0xa4, 0x9f, 0xce, 0xb3, 0xfa, 0x95, 0x17, 0xb4, + 0x88, 0xfa, 0xae, 0x35, 0x6d, 0x28, 0xb3, 0xd2, 0x6, 0xa9, + 0x9, 0xfe, 0x2a, 0x78, 0xbf, 0x84, 0xff, 00, 0x10, 0xaf, + 0x2f, 0x3a, 0x37, 0x88, 0x61, 0xe8, 0x73, 0xff, 00, 0x2, + 0xa6, 0x95, 0xf1, 0xc, 0x3d, 0x50, 0x9f, 0xa3, 0x54, 0xbc, + 0xbe, 0x1d, 0x24, 0x4f, 0xb1, 0xc7, 0x2f, 0xb2, 0x9f, 0xcc, + 0xf5, 0x51, 0x77, 0x11, 0xfe, 0x2a, 0x70, 0x9e, 0x33, 0xfc, + 0x55, 0xe5, 0x3, 0x52, 0xd7, 0xa1, 0xfb, 0xd0, 0x39, 0xa7, + 0x7f, 0xc2, 0x4d, 0xaa, 0xc5, 0xf7, 0xe0, 0x93, 0xfe, 0xf9, + 0xa9, 0x79, 0x77, 0x69, 0x12, 0xd6, 0x32, 0x3b, 0xd2, 0x3d, + 0x58, 0x4c, 0xbd, 0x9a, 0x9e, 0xb3, 0x11, 0xd2, 0x43, 0xf9, + 0xd7, 0x94, 0x2f, 0x8d, 0x6f, 0x53, 0xef, 0x42, 0xff, 00, + 0x8a, 0x9a, 0x95, 0x3e, 0x20, 0x4a, 0xbf, 0x79, 0x18, 0x7e, + 0x6, 0xb3, 0x79, 0x6c, 0xfa, 0x32, 0x7d, 0xae, 0x22, 0x3b, + 0xd2, 0x67, 0xaa, 0xad, 0xd4, 0x8b, 0xd2, 0x56, 0x1f, 0x8d, + 0x4c, 0x9a, 0xa5, 0xda, 0x7d, 0xdb, 0x89, 0x7, 0xd1, 0xab, + 0xcb, 0x23, 0xf8, 0x88, 0xbd, 0xc1, 0x15, 0x66, 0x3f, 0x88, + 0x50, 0x9e, 0xac, 0x6b, 0x37, 0x97, 0x55, 0x5d, 0x3, 0xeb, + 0xb5, 0x23, 0xbc, 0x64, 0x8f, 0x51, 0x8f, 0xc4, 0x3a, 0x8c, + 0x47, 0x2b, 0x75, 0x27, 0xfd, 0xf4, 0x6a, 0xdc, 0x5e, 0x33, + 0xd6, 0x22, 0xfb, 0xb7, 0x8e, 0x3f, 0x1a, 0xf2, 0xd8, 0xfc, + 0x7d, 0x6e, 0x7f, 0x8c, 0xd4, 0xeb, 0xe3, 0xab, 0x6c, 0x64, + 0xcb, 0x8a, 0xcf, 0xea, 0x35, 0xa3, 0xb2, 0x34, 0x59, 0xa4, + 0xa3, 0xd6, 0x4b, 0xef, 0x3d, 0x56, 0x1f, 0x88, 0x9a, 0xe4, + 0x3d, 0x2e, 0xd8, 0xfd, 0x4d, 0x5e, 0x8f, 0xe2, 0xe6, 0xbd, + 0x7, 0xfc, 0xbc, 0xd7, 0x8b, 0x5c, 0x7c, 0x42, 0xb4, 0x88, + 0x1f, 0xde, 0xd6, 0x16, 0xa7, 0xf1, 0x4e, 0xde, 0x30, 0x76, + 0x36, 0xe3, 0x5d, 0x14, 0xf0, 0x78, 0xa7, 0xb3, 0x6b, 0xe6, + 0xcd, 0x16, 0x73, 0x5f, 0x6a, 0x6e, 0x4c, 0xfa, 0x2f, 0xfe, + 0x17, 0xe6, 0xb1, 0x62, 0x32, 0xd3, 0xee, 0x23, 0xde, 0xb8, + 0x5f, 0x88, 0x3f, 0xb4, 0xad, 0xfd, 0xed, 0x94, 0xd0, 0xbd, + 0xe3, 0x7c, 0xc3, 0x5, 0x1, 0xe2, 0xbe, 0x7b, 0xd6, 0x7e, + 0x22, 0xde, 0x5f, 0x16, 0x58, 0x89, 0x55, 0x35, 0x99, 0xe1, + 0xdf, 0xb, 0xf8, 0x87, 0xe2, 0x26, 0xbb, 0x6f, 0xa5, 0xe8, + 0xd6, 0x17, 0x3a, 0xae, 0xa3, 0x70, 0xdb, 0x63, 0x82, 0x4, + 0x2c, 0x4f, 0xf8, 0x1, 0xea, 0x78, 0x15, 0xed, 0xd0, 0xc0, + 0xd4, 0x4a, 0xd5, 0x66, 0xdf, 0x95, 0xcd, 0xe3, 0x8b, 0xcc, + 0x71, 0x5e, 0xe5, 0x49, 0xf2, 0xc5, 0xf4, 0xea, 0xc8, 0x7c, + 0x53, 0xe2, 0xcb, 0x9f, 0x10, 0x5d, 0x33, 0xb3, 0x33, 0x64, + 0xf0, 0x7, 0x7a, 0xfb, 0xf3, 0xf6, 0x15, 0xfd, 0x91, 0x66, + 0xf0, 0x1a, 0x45, 0xf1, 0xf, 0xc6, 0x76, 0x5e, 0x5f, 0x88, + 0xee, 0x13, 0x3a, 0x5d, 0x94, 0x87, 0x26, 0xce, 0x26, 0x5e, + 0x64, 0x71, 0xda, 0x46, 0x7, 0xa7, 0xf0, 0x8f, 0x73, 0xc6, + 0xcf, 0xec, 0xb3, 0xfb, 0xb, 0xe9, 0xff, 00, 0xc, 0x65, + 0xb7, 0xf1, 0x37, 0x8d, 0xd2, 0xdf, 0x57, 0xf1, 0x3a, 0x10, + 0xf6, 0xd6, 0x6a, 0x7c, 0xcb, 0x7b, 0x2e, 0x3a, 0x9c, 0x8c, + 0x3c, 0x9e, 0xfd, 0x7, 0x6c, 0xf5, 0xaf, 0xae, 0xab, 0xe9, + 0xf0, 0xf8, 0x75, 0x4, 0x9b, 0x5e, 0x88, 0xfd, 0xf, 0x26, + 0xca, 0x56, 0x12, 0x2a, 0xa5, 0x45, 0x67, 0xd1, 0x7f, 0x9f, + 0x98, 0x51, 0x45, 0x15, 0xe8, 0x1f, 0x58, 0x14, 0x51, 0x45, + 00, 0x14, 0x51, 0x45, 00, 0x14, 0x51, 0x45, 00, 0x14, + 0x51, 0x45, 00, 0x14, 0x51, 0x45, 00, 0x14, 0x51, 0x45, + 00, 0x14, 0x51, 0x45, 00, 0x14, 0x51, 0x45, 00, 0x14, + 0x51, 0x45, 00, 0x14, 0x51, 0x45, 00, 0x14, 0x51, 0x45, + 00, 0x14, 0x51, 0x45, 00, 0x14, 0x51, 0x45, 00, 0x14, + 0x51, 0x45, 00, 0x14, 0x51, 0x45, 00, 0x14, 0x51, 0x45, + 00, 0x14, 0x51, 0x45, 00, 0x14, 0x51, 0x45, 00, 0x14, + 0x51, 0x45, 00, 0x14, 0x51, 0x45, 00, 0x14, 0x51, 0x45, + 00, 0x14, 0x51, 0x45, 00, 0x14, 0x51, 0x45, 00, 0x14, + 0x51, 0x45, 00, 0x14, 0x51, 0x45, 00, 0x14, 0x51, 0x45, + 00, 0x14, 0x51, 0x45, 00, 0x14, 0x51, 0x45, 00, 0x14, + 0x51, 0x45, 00, 0x14, 0x51, 0x45, 00, 0x14, 0x51, 0x45, + 00, 0x14, 0x51, 0x45, 00, 0x14, 0x51, 0x45, 00, 0x14, + 0x51, 0x45, 00, 0x21, 00, 0xf5, 0xa8, 0xa5, 0xb3, 0xb7, + 0x9b, 0xfd, 0x64, 0x11, 0xc9, 0xfe, 0xf2, 0x3, 0x45, 0x14, + 0xad, 0x71, 0x5a, 0xe5, 0x19, 0xfc, 0x2d, 0xa3, 0x5c, 0x92, + 0x66, 0xd2, 0x2c, 0x65, 0x27, 0xbb, 0xdb, 0x21, 0xfe, 0x95, + 0x9b, 0x71, 0xf0, 0xcf, 0xc2, 0x77, 0x44, 0x99, 0x7c, 0x3b, + 0xa6, 0xb1, 0x3f, 0xf4, 0xec, 0xa3, 0xf9, 0xa, 0x28, 0xa8, + 0x74, 0xe0, 0xf7, 0x8a, 0x33, 0x74, 0xa9, 0xcb, 0x78, 0xaf, + 0xb8, 0xc7, 0xbb, 0xf8, 0x13, 0xe0, 0x5b, 0xdc, 0xef, 0xf0, + 0xfd, 0xba, 0x93, 0xde, 0x36, 0x65, 0xfe, 0x46, 0xb1, 0xee, + 0xff, 00, 0x66, 0x4f, 0x1, 0x5d, 0x74, 0xd3, 0xa5, 0x87, + 0xfe, 0xb9, 0xcc, 0x7f, 0xae, 0x68, 0xa2, 0xb1, 0x78, 0x5a, + 0xf, 0x78, 0x2f, 0xb8, 0xc2, 0x58, 0x3c, 0x34, 0xb7, 0xa6, + 0xbe, 0xe4, 0x63, 0x5d, 0x7e, 0xc8, 0xbe, 0xa, 0x9f, 0xee, + 0x49, 0x7d, 0x17, 0xb0, 0x74, 0x3f, 0xfb, 0x2d, 0x64, 0x5d, + 0x7e, 0xc6, 0x1e, 0x19, 0x97, 0x3e, 0x4e, 0xa9, 0x77, 0x17, + 0xfb, 0xd1, 0xab, 0x7f, 0x85, 0x14, 0x56, 0x6f, 0x3, 0x86, + 0x7f, 0x60, 0xc5, 0xe5, 0xd8, 0x47, 0xff, 00, 0x2e, 0xd1, + 0x8b, 0x7b, 0xfb, 0x10, 0x69, 0xd2, 0x3, 0xe4, 0x6b, 0xdc, + 0xf6, 0x12, 0x5a, 0xff, 00, 0x83, 0x56, 0xd, 0xf7, 0xec, + 0x31, 0x71, 0x83, 0xf6, 0x7d, 0x5a, 0xca, 0x53, 0xd8, 0x49, + 0x1b, 0x2f, 0xf4, 0x34, 0x51, 0x59, 0xbc, 0xbb, 0xe, 0xf6, + 0x56, 0xf9, 0xb3, 0x27, 0x95, 0x61, 0x1f, 0xd9, 0xb7, 0xcd, + 0x98, 0x17, 0xdf, 0xb0, 0xce, 0xb8, 0xa0, 0xf9, 0x6d, 0xa7, + 0x4f, 0xec, 0xb2, 0x63, 0xf9, 0xa8, 0xae, 0x7e, 0xff, 00, + 0xf6, 0x24, 0xf1, 0x44, 0x59, 0xd9, 0xa5, 0xc1, 0x37, 0xbc, + 0x73, 0x47, 0xfd, 0x5a, 0x8a, 0x2b, 0x29, 0x65, 0xb4, 0xba, + 0x37, 0xf7, 0xff, 00, 0xc0, 0x39, 0xe5, 0x93, 0x61, 0xba, + 0x37, 0xf7, 0xff, 00, 0xc0, 0x30, 0x2f, 0x3f, 0x63, 0x6f, + 0x16, 0x43, 0xff, 00, 0x32, 0xfc, 0xed, 0xff, 00, 0x5c, + 0xd9, 0x5b, 0xf9, 0x1a, 0xc1, 0xbf, 0xfd, 0x94, 0x3c, 0x55, + 0x6d, 0x90, 0x7c, 0x3f, 0xa9, 0x8f, 0x75, 0x85, 0x98, 0x7e, + 0x82, 0x8a, 0x2b, 0x86, 0xa6, 0x16, 0x34, 0xf6, 0x93, 0xfe, + 0xbe, 0x47, 0x97, 0x5f, 0x2c, 0xa3, 0x4d, 0x68, 0xdf, 0xe1, + 0xfe, 0x46, 0xb, 0x7e, 0xcc, 0x1e, 0x23, 0xb9, 0x9f, 0xcb, + 0x5d, 0x1e, 0xfc, 0xbe, 0x7a, 0x1b, 0x77, 0x3f, 0xd2, 0xb4, + 0x34, 0xff, 00, 0xd8, 0x8f, 0xc7, 0x7a, 0xc4, 0xaa, 0xb0, + 0xe8, 0x57, 0x10, 0x8c, 0xfd, 0xfb, 0x8c, 0x44, 0xb8, 0xf5, + 0xf9, 0x88, 0xa2, 0x8a, 0x58, 0x7a, 0x4e, 0xa4, 0xac, 0xe4, + 0xff, 00, 0xf, 0xf2, 0x38, 0x68, 0x65, 0x54, 0x31, 0x4e, + 0xd3, 0x6d, 0x7a, 0x5b, 0xfc, 0x8f, 0x62, 0xf8, 0x79, 0xff, + 00, 0x4, 0xdc, 0x88, 0x3a, 0x5c, 0x78, 0xc3, 0x5c, 0x8, + 0xa0, 0x83, 0xf6, 0x3d, 0x34, 0x6e, 0x63, 0xec, 0x64, 0x61, + 0x81, 0xf8, 0x3, 0xf5, 0xaf, 0xae, 0x3e, 0x1d, 0xfc, 0x27, + 0xf0, 0xaf, 0xc2, 0xad, 0x29, 0x6c, 0x3c, 0x33, 0xa3, 0xdb, + 0xe9, 0xc9, 0x8c, 0x3c, 0xca, 0xbb, 0xa6, 0x97, 0xdd, 0xdc, + 0xf2, 0x68, 0xa2, 0xbe, 0x82, 0x14, 0x61, 0x4f, 0x6d, 0xcf, + 0xac, 0xc1, 0xe5, 0x98, 0x5c, 0xe, 0xb4, 0x61, 0xaf, 0x77, + 0xab, 0xfb, 0xff, 00, 0xc8, 0xeb, 0xa8, 0xa2, 0x8a, 0xd8, + 0xf5, 0x42, 0x8a, 0x28, 0xa0, 0x2, 0x8a, 0x28, 0xa0, 0xf, + 0xff, 0xd9, 0}; + +static const char data_runtime_shtml[] = { + /* /runtime.shtml */ + 0x2f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, + 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, + 0x43, 0x20, 0x22, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f, + 0x2f, 0x44, 0x54, 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20, + 0x34, 0x2e, 0x30, 0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x45, + 0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, + 0x67, 0x2f, 0x54, 0x52, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x34, + 0x2f, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x2e, 0x64, 0x74, 0x64, + 0x22, 0x3e, 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, + 0xd, 0xa, 0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, + 0xd, 0xa, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x74, + 0x6c, 0x65, 0x3e, 0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, + 0x53, 0x2e, 0x6f, 0x72, 0x67, 0x20, 0x75, 0x49, 0x50, 0x20, + 0x57, 0x45, 0x42, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x20, 0x64, 0x65, 0x6d, 0x6f, 0x3c, 0x2f, 0x74, 0x69, 0x74, + 0x6c, 0x65, 0x3e, 0xd, 0xa, 0x20, 0x20, 0x3c, 0x2f, 0x68, + 0x65, 0x61, 0x64, 0x3e, 0xd, 0xa, 0x20, 0x20, 0x3c, 0x42, + 0x4f, 0x44, 0x59, 0x20, 0x6f, 0x6e, 0x4c, 0x6f, 0x61, 0x64, + 0x3d, 0x22, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x73, + 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x28, + 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x6c, 0x6f, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x68, 0x72, 0x65, 0x66, 0x3d, + 0x27, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, + 0x68, 0x74, 0x6d, 0x6c, 0x27, 0x26, 0x71, 0x75, 0x6f, 0x74, + 0x3b, 0x2c, 0x32, 0x30, 0x30, 0x30, 0x29, 0x22, 0x3e, 0xd, + 0xa, 0x3c, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x66, 0x61, 0x63, + 0x65, 0x3d, 0x22, 0x61, 0x72, 0x69, 0x61, 0x6c, 0x22, 0x3e, + 0xd, 0xa, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, + 0x22, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x73, 0x68, 0x74, + 0x6d, 0x6c, 0x22, 0x3e, 0x54, 0x61, 0x73, 0x6b, 0x20, 0x53, + 0x74, 0x61, 0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, + 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, + 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, + 0x22, 0x3e, 0x52, 0x75, 0x6e, 0x20, 0x54, 0x69, 0x6d, 0x65, + 0x20, 0x53, 0x74, 0x61, 0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, + 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, + 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x73, + 0x74, 0x61, 0x74, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, + 0x22, 0x3e, 0x54, 0x43, 0x50, 0x20, 0x53, 0x74, 0x61, 0x74, + 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, + 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, + 0x65, 0x66, 0x3d, 0x22, 0x74, 0x63, 0x70, 0x2e, 0x73, 0x68, + 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x2f, 0x61, 0x3e, + 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, + 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, + 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, + 0x66, 0x72, 0x65, 0x65, 0x72, 0x74, 0x6f, 0x73, 0x2e, 0x6f, + 0x72, 0x67, 0x2f, 0x22, 0x3e, 0x46, 0x72, 0x65, 0x65, 0x52, + 0x54, 0x4f, 0x53, 0x20, 0x48, 0x6f, 0x6d, 0x65, 0x70, 0x61, + 0x67, 0x65, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, + 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, + 0x72, 0x65, 0x66, 0x3d, 0x22, 0x69, 0x6f, 0x2e, 0x73, 0x68, + 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x49, 0x4f, 0x3c, 0x2f, 0x61, + 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, + 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, + 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x6a, 0x70, 0x67, 0x22, 0x3e, + 0x33, 0x37, 0x4b, 0x20, 0x6a, 0x70, 0x67, 0x3c, 0x2f, 0x61, + 0x3e, 0xd, 0xa, 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x70, 0x3e, + 0xd, 0xa, 0x3c, 0x68, 0x72, 0x3e, 0xd, 0xa, 0x3c, 0x62, + 0x72, 0x3e, 0x3c, 0x70, 0x3e, 0xd, 0xa, 0x3c, 0x68, 0x32, + 0x3e, 0x52, 0x75, 0x6e, 0x2d, 0x74, 0x69, 0x6d, 0x65, 0x20, + 0x73, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, + 0x3c, 0x2f, 0x68, 0x32, 0x3e, 0xd, 0xa, 0x50, 0x61, 0x67, + 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x72, 0x65, 0x66, + 0x72, 0x65, 0x73, 0x68, 0x20, 0x65, 0x76, 0x65, 0x72, 0x79, + 0x20, 0x32, 0x20, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, + 0x2e, 0x3c, 0x70, 0x3e, 0xd, 0xa, 0x3c, 0x66, 0x6f, 0x6e, + 0x74, 0x20, 0x66, 0x61, 0x63, 0x65, 0x3d, 0x22, 0x63, 0x6f, + 0x75, 0x72, 0x69, 0x65, 0x72, 0x22, 0x3e, 0x3c, 0x70, 0x72, + 0x65, 0x3e, 0x54, 0x61, 0x73, 0x6b, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x62, + 0x73, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x25, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x3c, 0x62, + 0x72, 0x3e, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, + 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, + 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, + 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, + 0x2a, 0x2a, 0x3c, 0x62, 0x72, 0x3e, 0xd, 0xa, 0x25, 0x21, + 0x20, 0x72, 0x75, 0x6e, 0x2d, 0x74, 0x69, 0x6d, 0x65, 0xd, + 0xa, 0x3c, 0x2f, 0x70, 0x72, 0x65, 0x3e, 0x3c, 0x2f, 0x66, + 0x6f, 0x6e, 0x74, 0x3e, 0xd, 0xa, 0x3c, 0x2f, 0x66, 0x6f, + 0x6e, 0x74, 0x3e, 0xd, 0xa, 0x3c, 0x2f, 0x62, 0x6f, 0x64, + 0x79, 0x3e, 0xd, 0xa, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, + 0x3e, 0xd, 0xa, 0xd, 0xa, 0}; + +static const char data_stats_shtml[] = { + /* /stats.shtml */ + 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, + 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, + 0x43, 0x20, 0x22, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f, + 0x2f, 0x44, 0x54, 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20, + 0x34, 0x2e, 0x30, 0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x45, + 0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, + 0x67, 0x2f, 0x54, 0x52, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x34, + 0x2f, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x2e, 0x64, 0x74, 0x64, + 0x22, 0x3e, 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, + 0xd, 0xa, 0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, + 0xd, 0xa, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x74, + 0x6c, 0x65, 0x3e, 0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, + 0x53, 0x2e, 0x6f, 0x72, 0x67, 0x20, 0x75, 0x49, 0x50, 0x20, + 0x57, 0x45, 0x42, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x20, 0x64, 0x65, 0x6d, 0x6f, 0x3c, 0x2f, 0x74, 0x69, 0x74, + 0x6c, 0x65, 0x3e, 0xd, 0xa, 0x20, 0x20, 0x3c, 0x2f, 0x68, + 0x65, 0x61, 0x64, 0x3e, 0xd, 0xa, 0x20, 0x20, 0x3c, 0x42, + 0x4f, 0x44, 0x59, 0x3e, 0xd, 0xa, 0x3c, 0x66, 0x6f, 0x6e, + 0x74, 0x20, 0x66, 0x61, 0x63, 0x65, 0x3d, 0x22, 0x61, 0x72, + 0x69, 0x61, 0x6c, 0x22, 0x3e, 0xd, 0xa, 0x3c, 0x61, 0x20, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x54, + 0x61, 0x73, 0x6b, 0x20, 0x53, 0x74, 0x61, 0x74, 0x73, 0x3c, + 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, + 0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, + 0x3d, 0x22, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x52, 0x75, 0x6e, + 0x20, 0x54, 0x69, 0x6d, 0x65, 0x20, 0x53, 0x74, 0x61, 0x74, + 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, + 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, + 0x65, 0x66, 0x3d, 0x22, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, + 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x54, 0x43, 0x50, + 0x20, 0x53, 0x74, 0x61, 0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, + 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, + 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x74, + 0x63, 0x70, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, + 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, + 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, + 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x66, 0x72, 0x65, 0x65, 0x72, + 0x74, 0x6f, 0x73, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x22, 0x3e, + 0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, 0x53, 0x20, 0x48, + 0x6f, 0x6d, 0x65, 0x70, 0x61, 0x67, 0x65, 0x3c, 0x2f, 0x61, + 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, + 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, + 0x69, 0x6f, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, + 0x49, 0x4f, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, + 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, + 0x72, 0x65, 0x66, 0x3d, 0x22, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, + 0x6a, 0x70, 0x67, 0x22, 0x3e, 0x33, 0x37, 0x4b, 0x20, 0x6a, + 0x70, 0x67, 0x3c, 0x2f, 0x61, 0x3e, 0xd, 0xa, 0x3c, 0x62, + 0x72, 0x3e, 0x3c, 0x70, 0x3e, 0xd, 0xa, 0x3c, 0x68, 0x72, + 0x3e, 0xd, 0xa, 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x70, 0x3e, + 0xd, 0xa, 0x3c, 0x68, 0x32, 0x3e, 0x4e, 0x65, 0x74, 0x77, + 0x6f, 0x72, 0x6b, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x73, + 0x74, 0x69, 0x63, 0x73, 0x3c, 0x2f, 0x68, 0x32, 0x3e, 0xd, + 0xa, 0x3c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x77, 0x69, + 0x64, 0x74, 0x68, 0x3d, 0x22, 0x33, 0x30, 0x30, 0x22, 0x20, + 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3d, 0x22, 0x30, 0x22, + 0x3e, 0xd, 0xa, 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x64, + 0x20, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3d, 0x22, 0x6c, 0x65, + 0x66, 0x74, 0x22, 0x3e, 0x3c, 0x66, 0x6f, 0x6e, 0x74, 0x20, + 0x66, 0x61, 0x63, 0x65, 0x3d, 0x22, 0x63, 0x6f, 0x75, 0x72, + 0x69, 0x65, 0x72, 0x22, 0x3e, 0x3c, 0x70, 0x72, 0x65, 0x3e, + 0xd, 0xa, 0x49, 0x50, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, + 0x74, 0x73, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, + 0x64, 0xd, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, + 0x65, 0x74, 0x73, 0x20, 0x73, 0x65, 0x6e, 0x74, 0xd, 0xa, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x64, 0x65, + 0x64, 0xd, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x44, 0x72, 0x6f, 0x70, + 0x70, 0x65, 0x64, 0xd, 0xa, 0x49, 0x50, 0x20, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x73, 0x20, 0x20, 0x20, 0x20, 0x49, 0x50, + 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2f, 0x68, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0xd, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x50, 0x20, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x20, 0x68, 0x69, + 0x67, 0x68, 0x20, 0x62, 0x79, 0x74, 0x65, 0xd, 0xa, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x49, 0x50, 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x2c, 0x20, 0x6c, 0x6f, 0x77, 0x20, 0x62, 0x79, 0x74, + 0x65, 0xd, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x50, 0x20, 0x66, + 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0xd, 0xa, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, + 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0xd, 0xa, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x57, 0x72, 0x6f, 0x6e, 0x67, 0x20, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0xd, 0xa, 0x49, + 0x43, 0x4d, 0x50, 0x9, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, + 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, 0x72, 0x65, 0x63, + 0x65, 0x69, 0x76, 0x65, 0x64, 0xd, 0xa, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, 0x73, 0x65, + 0x6e, 0x74, 0xd, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, + 0x6b, 0x65, 0x74, 0x73, 0x20, 0x64, 0x72, 0x6f, 0x70, 0x70, + 0x65, 0x64, 0xd, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, + 0x65, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0xd, 0xa, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, + 0x6d, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0xd, 0xa, + 0x54, 0x43, 0x50, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, + 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0xd, + 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, + 0x73, 0x20, 0x73, 0x65, 0x6e, 0x74, 0xd, 0xa, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, 0x64, + 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0xd, 0xa, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x20, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0xd, 0xa, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x44, 0x61, 0x74, 0x61, 0x20, 0x70, 0x61, 0x63, 0x6b, + 0x65, 0x74, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75, + 0x74, 0x20, 0x41, 0x43, 0x4b, 0x73, 0xd, 0xa, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x52, 0x65, 0x73, 0x65, 0x74, 0x73, 0xd, 0xa, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x52, 0x65, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x61, 0xd, 0xa, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x53, 0x79, 0x6e, 0x20, 0x74, 0x6f, 0x20, + 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x20, 0x70, 0x6f, 0x72, + 0x74, 0xd, 0xa, 0x55, 0x44, 0x50, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, + 0x65, 0x74, 0x73, 0x20, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, + 0x64, 0xd, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, + 0x65, 0x74, 0x73, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, + 0x65, 0x64, 0xd, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, + 0x6b, 0x65, 0x74, 0x73, 0x20, 0x73, 0x65, 0x6e, 0x74, 0xd, + 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, + 0x73, 0x20, 0x63, 0x68, 0x6b, 0x65, 0x72, 0x72, 0xd, 0xa, + 0x9, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4e, 0x6f, 0x20, 0x63, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x61, 0x76, 0x61, 0x6c, 0x69, 0x61, 0x62, 0x6c, 0x65, 0xd, + 0xa, 0x3c, 0x2f, 0x70, 0x72, 0x65, 0x3e, 0x3c, 0x2f, 0x66, + 0x6f, 0x6e, 0x74, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, + 0x74, 0x64, 0x3e, 0x3c, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x66, + 0x61, 0x63, 0x65, 0x3d, 0x22, 0x63, 0x6f, 0x75, 0x72, 0x69, + 0x65, 0x72, 0x22, 0x3e, 0x3c, 0x70, 0x72, 0x65, 0x3e, 0x25, + 0x21, 0x20, 0x6e, 0x65, 0x74, 0x2d, 0x73, 0x74, 0x61, 0x74, + 0x73, 0xd, 0xa, 0x3c, 0x2f, 0x70, 0x72, 0x65, 0x3e, 0x3c, + 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0x3c, 0x2f, 0x74, 0x64, + 0x3e, 0x3c, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0xd, + 0xa, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0xd, 0xa, + 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xd, 0xa, 0x3c, + 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xd, 0xa, 0}; + +static const char data_tcp_shtml[] = { + /* /tcp.shtml */ + 0x2f, 0x74, 0x63, 0x70, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, + 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, + 0x43, 0x20, 0x22, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f, + 0x2f, 0x44, 0x54, 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20, + 0x34, 0x2e, 0x30, 0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x45, + 0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, + 0x67, 0x2f, 0x54, 0x52, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x34, + 0x2f, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x2e, 0x64, 0x74, 0x64, + 0x22, 0x3e, 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, + 0xd, 0xa, 0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, + 0xd, 0xa, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x74, + 0x6c, 0x65, 0x3e, 0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, + 0x53, 0x2e, 0x6f, 0x72, 0x67, 0x20, 0x75, 0x49, 0x50, 0x20, + 0x57, 0x45, 0x42, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x20, 0x64, 0x65, 0x6d, 0x6f, 0x3c, 0x2f, 0x74, 0x69, 0x74, + 0x6c, 0x65, 0x3e, 0xd, 0xa, 0x20, 0x20, 0x3c, 0x2f, 0x68, + 0x65, 0x61, 0x64, 0x3e, 0xd, 0xa, 0x20, 0x20, 0x3c, 0x42, + 0x4f, 0x44, 0x59, 0x3e, 0xd, 0xa, 0x3c, 0x66, 0x6f, 0x6e, + 0x74, 0x20, 0x66, 0x61, 0x63, 0x65, 0x3d, 0x22, 0x61, 0x72, + 0x69, 0x61, 0x6c, 0x22, 0x3e, 0xd, 0xa, 0x3c, 0x61, 0x20, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x54, + 0x61, 0x73, 0x6b, 0x20, 0x53, 0x74, 0x61, 0x74, 0x73, 0x3c, + 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, + 0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, + 0x3d, 0x22, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x52, 0x75, 0x6e, + 0x20, 0x54, 0x69, 0x6d, 0x65, 0x20, 0x53, 0x74, 0x61, 0x74, + 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, + 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, + 0x65, 0x66, 0x3d, 0x22, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, + 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x54, 0x43, 0x50, + 0x20, 0x53, 0x74, 0x61, 0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, + 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, + 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x74, + 0x63, 0x70, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, + 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, + 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, + 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x66, 0x72, 0x65, 0x65, 0x72, + 0x74, 0x6f, 0x73, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x22, 0x3e, + 0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, 0x53, 0x20, 0x48, + 0x6f, 0x6d, 0x65, 0x70, 0x61, 0x67, 0x65, 0x3c, 0x2f, 0x61, + 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, + 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, + 0x69, 0x6f, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, + 0x49, 0x4f, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, + 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, + 0x72, 0x65, 0x66, 0x3d, 0x22, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, + 0x6a, 0x70, 0x67, 0x22, 0x3e, 0x33, 0x37, 0x4b, 0x20, 0x6a, + 0x70, 0x67, 0x3c, 0x2f, 0x61, 0x3e, 0xd, 0xa, 0x3c, 0x62, + 0x72, 0x3e, 0x3c, 0x70, 0x3e, 0xd, 0xa, 0x3c, 0x68, 0x72, + 0x3e, 0xd, 0xa, 0x3c, 0x62, 0x72, 0x3e, 0xd, 0xa, 0x3c, + 0x68, 0x32, 0x3e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, + 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x3c, 0x2f, 0x68, 0x32, 0x3e, 0xd, 0xa, 0x3c, + 0x70, 0x3e, 0xd, 0xa, 0x3c, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x3e, 0xd, 0xa, 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x68, + 0x3e, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x3c, 0x2f, 0x74, 0x68, + 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x52, 0x65, 0x6d, 0x6f, 0x74, + 0x65, 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x3c, 0x2f, 0x74, 0x68, 0x3e, + 0x3c, 0x74, 0x68, 0x3e, 0x52, 0x65, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x3c, + 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x54, 0x69, + 0x6d, 0x65, 0x72, 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, + 0x68, 0x3e, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x3c, 0x2f, 0x74, + 0x68, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0xd, 0xa, 0x25, + 0x21, 0x20, 0x74, 0x63, 0x70, 0x2d, 0x63, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0xd, 0xa, 0x3c, + 0x2f, 0x70, 0x72, 0x65, 0x3e, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, + 0x74, 0x3e, 0xd, 0xa, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, + 0x3e, 0xd, 0xa, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, + 0xd, 0xa, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xd, + 0xa, 0xd, 0xa, 0}; + +const struct httpd_fsdata_file file_404_html[] = {{NULL, data_404_html, data_404_html + 10, sizeof(data_404_html) - 10}}; + +const struct httpd_fsdata_file file_index_html[] = {{file_404_html, data_index_html, data_index_html + 12, sizeof(data_index_html) - 12}}; + +const struct httpd_fsdata_file file_index_shtml[] = {{file_index_html, data_index_shtml, data_index_shtml + 13, sizeof(data_index_shtml) - 13}}; + +const struct httpd_fsdata_file file_io_shtml[] = {{file_index_shtml, data_io_shtml, data_io_shtml + 10, sizeof(data_io_shtml) - 10}}; + +const struct httpd_fsdata_file file_logo_jpg[] = {{file_io_shtml, data_logo_jpg, data_logo_jpg + 10, sizeof(data_logo_jpg) - 10}}; + +const struct httpd_fsdata_file file_runtime_shtml[] = {{file_logo_jpg, data_runtime_shtml, data_runtime_shtml + 15, sizeof(data_runtime_shtml) - 15}}; + +const struct httpd_fsdata_file file_stats_shtml[] = {{file_runtime_shtml, data_stats_shtml, data_stats_shtml + 13, sizeof(data_stats_shtml) - 13}}; + +const struct httpd_fsdata_file file_tcp_shtml[] = {{file_stats_shtml, data_tcp_shtml, data_tcp_shtml + 11, sizeof(data_tcp_shtml) - 11}}; + +#define HTTPD_FS_ROOT file_tcp_shtml + +#define HTTPD_FS_NUMFILES 8 diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/makefsdata b/Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/makefsdata new file mode 100644 index 000000000..a953cdd76 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/makefsdata @@ -0,0 +1,79 @@ +#!/usr/bin/perl + +open(OUTPUT, "> httpd-fsdata.c"); + +chdir("httpd-fs"); + +opendir(DIR, "."); +@files = grep { !/^\./ && !/(CVS|~)/ } readdir(DIR); +closedir(DIR); + +foreach $file (@files) { + + if(-d $file && $file !~ /^\./) { + print "Processing directory $file\n"; + opendir(DIR, $file); + @newfiles = grep { !/^\./ && !/(CVS|~)/ } readdir(DIR); + closedir(DIR); + printf "Adding files @newfiles\n"; + @files = (@files, map { $_ = "$file/$_" } @newfiles); + next; + } +} + +foreach $file (@files) { + if(-f $file) { + + print "Adding file $file\n"; + + open(FILE, $file) || die "Could not open file $file\n"; + binmode FILE; + + $file =~ s-^-/-; + $fvar = $file; + $fvar =~ s-/-_-g; + $fvar =~ s-\.-_-g; + # for AVR, add PROGMEM here + print(OUTPUT "static const char data".$fvar."[] = {\n"); + print(OUTPUT "\t/* $file */\n\t"); + for($j = 0; $j < length($file); $j++) { + printf(OUTPUT "%#02x, ", unpack("C", substr($file, $j, 1))); + } + printf(OUTPUT "0,\n"); + + + $i = 0; + while(read(FILE, $data, 1)) { + if($i == 0) { + print(OUTPUT "\t"); + } + printf(OUTPUT "%#02x, ", unpack("C", $data)); + $i++; + if($i == 10) { + print(OUTPUT "\n"); + $i = 0; + } + } + print(OUTPUT "0};\n\n"); + close(FILE); + push(@fvars, $fvar); + push(@pfiles, $file); + } +} + +for($i = 0; $i < @fvars; $i++) { + $file = $pfiles[$i]; + $fvar = $fvars[$i]; + + if($i == 0) { + $prevfile = "NULL"; + } else { + $prevfile = "file" . $fvars[$i - 1]; + } + print(OUTPUT "const struct httpd_fsdata_file file".$fvar."[] = {{$prevfile, data$fvar, "); + print(OUTPUT "data$fvar + ". (length($file) + 1) .", "); + print(OUTPUT "sizeof(data$fvar) - ". (length($file) + 1) ."}};\n\n"); +} + +print(OUTPUT "#define HTTPD_FS_ROOT file$fvars[$i - 1]\n\n"); +print(OUTPUT "#define HTTPD_FS_NUMFILES $i\n"); diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/uip-conf.h b/Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/uip-conf.h new file mode 100644 index 000000000..004bbb59a --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/uip-conf.h @@ -0,0 +1,161 @@ +/** + * \addtogroup uipopt + * @{ + */ + +/** + * \name Project-specific configuration options + * @{ + * + * uIP has a number of configuration options that can be overridden + * for each project. These are kept in a project-specific uip-conf.h + * file and all configuration names have the prefix UIP_CONF. + */ + +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * $Id: uip-conf.h,v 1.6 2006/06/12 08:00:31 adam Exp $ + */ + +/** + * \file + * An example uIP configuration file + * \author + * Adam Dunkels + */ + +#ifndef __UIP_CONF_H__ +#define __UIP_CONF_H__ + +#define UIP_CONF_EXTERNAL_BUFFER +#define UIP_CONF_PROCESS_HTTPD_FORMS 1 + +/** + * 8 bit datatype + * + * This typedef defines the 8-bit type used throughout uIP. + * + * \hideinitializer + */ +typedef unsigned char u8_t; + +/** + * 16 bit datatype + * + * This typedef defines the 16-bit type used throughout uIP. + * + * \hideinitializer + */ +typedef unsigned short u16_t; + +typedef unsigned long u32_t; + +/** + * Statistics datatype + * + * This typedef defines the dataype used for keeping statistics in + * uIP. + * + * \hideinitializer + */ +typedef unsigned short uip_stats_t; + +/** + * Maximum number of TCP connections. + * + * \hideinitializer + */ +#define UIP_CONF_MAX_CONNECTIONS 40 + +/** + * Maximum number of listening TCP ports. + * + * \hideinitializer + */ +#define UIP_CONF_MAX_LISTENPORTS 40 + +/** + * uIP buffer size. + * + * \hideinitializer + */ +#define UIP_CONF_BUFFER_SIZE 1480 + +/** + * CPU byte order. + * + * \hideinitializer + */ +#define UIP_CONF_BYTE_ORDER LITTLE_ENDIAN + +/** + * Logging on or off + * + * \hideinitializer + */ +#define UIP_CONF_LOGGING 0 + +/** + * UDP support on or off + * + * \hideinitializer + */ +#define UIP_CONF_UDP 0 + +/** + * UDP checksums on or off + * + * \hideinitializer + */ +#define UIP_CONF_UDP_CHECKSUMS 1 + +/** + * uIP statistics on or off + * + * \hideinitializer + */ +#define UIP_CONF_STATISTICS 1 + +/* Here we include the header file for the application(s) we use in + our project. */ +/*#include "smtp.h"*/ +/*#include "hello-world.h"*/ +/*#include "telnetd.h"*/ +#include "webserver.h" +/*#include "dhcpc.h"*/ +/*#include "resolv.h"*/ +/*#include "webclient.h"*/ + +#define CCIF +#endif /* __UIP_CONF_H__ */ + +/** @} */ +/** @} */ diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/webserver.h b/Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/webserver.h new file mode 100644 index 000000000..5267f0587 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/WebServer/webserver.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2002, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * $Id: webserver.h,v 1.2 2006/06/11 21:46:38 adam Exp $ + * + */ +#ifndef __WEBSERVER_H__ +#define __WEBSERVER_H__ + +#include "apps/httpd/httpd.h" + +typedef struct httpd_state uip_tcp_appstate_t; +/* UIP_APPCALL: the name of the application function. This function + must return void and take no arguments (i.e., C type "void + appfunc(void)"). */ +#define UIP_APPCALL httpd_appcall + + +#endif /* __WEBSERVER_H__ */ diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/main-blinky.c b/Demo/CORTEX_A2F200_IAR_and_Keil/main-blinky.c new file mode 100644 index 000000000..82b48f6e4 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/main-blinky.c @@ -0,0 +1,378 @@ +/* + FreeRTOS V7.0.0 - Copyright (C) 2011 Real Time Engineers Ltd. + + + FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by: + Atollic AB - Atollic provides professional embedded systems development + tools for C/C++ development, code analysis and test automation. + See http://www.atollic.com + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and 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 modification 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. +*/ + +/* + * main-blinky.c is included when the "Blinky" build configuration is used. + * main-full.c is included when the "Full" build configuration is used. + * + * main-blinky.c (this file) defines a very simple demo that creates two tasks, + * one queue, and one timer. It also demonstrates how Cortex-M3 interrupts can + * interact with FreeRTOS tasks/timers. + * + * This simple demo project runs on the SmartFusion A2F-EVAL-KIT evaluation + * board, which is populated with an A2F200M3F SmartFusion mixed signal FPGA. + * The A2F200M3F incorporates a Cortex-M3 microcontroller. + * + * The idle hook function: + * The idle hook function demonstrates how to query the amount of FreeRTOS heap + * space that is remaining (see vApplicationIdleHook() defined in this file). + * + * 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 it to + * 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 LED + * every 200 milliseconds. + * + * The LED Software Timer and the Button Interrupt: + * The user button SW1 is configured to generate an interrupt each time it is + * pressed. The interrupt service routine switches an 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 LED off again. + * Therefore, pressing the user button will turn the 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 ) + +/* The LED toggle by the queue receive task. */ +#define mainTASK_CONTROLLED_LED 0x01UL + +/* The LED turned on by the button interrupt, and turned off by the LED timer. */ +#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 off the + * LED defined by the mainTIMER_CONTROLLED_LED constant. + */ +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; + +/* Maintains the current LED output state. */ +static 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_SetPriority( GPIO8_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); + 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. */ + } +} diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/main-full.c b/Demo/CORTEX_A2F200_IAR_and_Keil/main-full.c new file mode 100644 index 000000000..d965dc8bf --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/main-full.c @@ -0,0 +1,618 @@ +/* + FreeRTOS V7.0.0 - Copyright (C) 2011 Real Time Engineers Ltd. + + + FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by: + Atollic AB - Atollic provides professional embedded systems development + tools for C/C++ development, code analysis and test automation. + See http://www.atollic.com + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and 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 modification 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. +*/ + +/* + * main-blinky.c is included when the "Blinky" build configuration is used. + * main-full.c is included when the "Full" build configuration is used. + * + * main-full.c (this file) defines a comprehensive demo that creates many + * tasks, queues, semaphores and timers. It also demonstrates how Cortex-M3 + * interrupts can interact with FreeRTOS tasks/timers, and implements a simple + * and small interactive web server. + * + * This project runs on the SmartFusion A2F-EVAL-KIT evaluation board, which + * is populated with an A2F200M3F SmartFusion mixed signal FPGA. The A2F200M3F + * incorporates a Cortex-M3 microcontroller. + * + * The main() Function: + * main() creates three demo specific software timers, one demo specific queue, + * and two demo specific tasks. It then creates a whole host of 'standard demo' + * tasks/queues/semaphores, before starting the scheduler. The demo specific + * tasks and timers are described in the comments here. The standard demo + * tasks are described on the FreeRTOS.org web site. + * + * The standard demo tasks provide no specific functionality. They are + * included to both test the FreeRTOS port, and provide examples of how the + * various FreeRTOS API functions can be used. + * + * The Demo Specific 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 Demo Specific Queue Receive Task: + * The queue receive task is implemented by the prvQueueReceiveTask() function + * in this file. prvQueueReceiveTask() sits in a loop that causes it to + * 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 LED + * every 200 milliseconds. + * + * The Demo Specific LED Software Timer and the Button Interrupt: + * The user button SW1 is configured to generate an interrupt each time it is + * pressed. The interrupt service routine switches an 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 LED off again. + * Therefore, pressing the user button will turn the LED on, and the LED will + * remain on until a full five seconds pass without the button being pressed. + * + * The Demo Specific OLED Software Timer: + * The OLED software timer is responsible for drawing a scrolling text message + * on the OLED. + * + * The Demo Specific "Check" Callback Function: + * This is called each time the 'check' timer expires. The check timer + * callback function inspects all the standard demo tasks to see if they are + * all executing as expected. The check timer is initially configured to + * expire every three seconds, but will shorted this to every 500ms if an error + * is ever discovered. The check timer callback toggles the LED defined by + * the mainCHECK_LED definition each time it executes. Therefore, if LED + * mainCHECK_LED is toggling every three seconds, then no error have been found. + * If LED mainCHECK_LED is toggling every 500ms, then at least one error has + * been found. The task in which the error was discovered is displayed at the + * bottom of the "task stats" page that is served by the embedded web server. + * + * The Demo Specific Idle Hook Function: + * The idle hook function demonstrates how to query the amount of FreeRTOS heap + * space that is remaining (see vApplicationIdleHook() defined in this file). + * + * The Web Server Task: + * The IP address used by the SmartFusion target is configured by the + * definitions configIP_ADDR0 to configIP_ADDR3, which are located in the + * FreeRTOSConfig.h header file. See the documentation page for this example + * on the http://www.FreeRTOS.org web site for further connection information. + */ + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" + +/* Microsemi drivers/libraries includes. */ +#include "mss_gpio.h" +#include "mss_watchdog.h" +#include "oled.h" + +/* Common demo includes. */ +#include "partest.h" +#include "flash.h" +#include "BlockQ.h" +#include "death.h" +#include "blocktim.h" +#include "semtest.h" +#include "GenQTest.h" +#include "QPeek.h" +#include "recmutex.h" +#include "TimerDemo.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 ) + +/* The LED toggled by the check timer callback function. */ +#define mainCHECK_LED 0x07UL + +/* The LED turned on by the button interrupt, and turned off by the LED timer. */ +#define mainTIMER_CONTROLLED_LED 0x06UL + +/* The LED toggle by the queue receive task. */ +#define mainTASK_CONTROLLED_LED 0x05UL + +/* Constant used by the standard timer test functions. */ +#define mainTIMER_TEST_PERIOD ( 50 ) + +/* Priorities used by the various different tasks. */ +#define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 1 ) +#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) +#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) +#define mainFLASH_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) +#define mainuIP_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY ) +#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY ) + +/* The WEB server uses string handling functions, which in turn use a bit more +stack than most of the other tasks. */ +#define mainuIP_STACK_SIZE ( configMINIMAL_STACK_SIZE * 3 ) + +/* The period at which the check timer will expire, in ms, provided no errors +have been reported by any of the standard demo tasks. */ +#define mainCHECK_TIMER_PERIOD_ms ( 3000UL ) + +/* The period at which the OLED timer will expire. Each time it expires, it's +callback function updates the OLED text. */ +#define mainOLED_PERIOD_ms ( 75UL ) + +/* The period at which the check timer will expire, in ms, if an error has been +reported in one of the standard demo tasks. */ +#define mainERROR_CHECK_TIMER_PERIOD_ms ( 500UL ) + +/* A zero block time. */ +#define mainDONT_BLOCK ( 0UL ) +/*-----------------------------------------------------------*/ + +/* + * 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 check timer callback function, as described at the top of this file. + */ +static void vCheckTimerCallback( xTimerHandle xTimer ); + +/* + * The OLED timer callback function, as described at the top of this file. + */ +static void vOLEDTimerCallback( xTimerHandle xHandle ); + +/* + * This is not a 'standard' partest function, so the prototype is not in + * partest.h, and is instead included here. + */ +void vParTestSetLEDFromISR( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE xValue ); + +/* + * Contains the implementation of the WEB server. + */ +extern void vuIP_Task( void *pvParameters ); + +/*-----------------------------------------------------------*/ + +/* The queue used by both application specific demo tasks defined in this file. */ +static xQueueHandle xQueue = NULL; + +/* The LED software timer. This uses vLEDTimerCallback() as it's callback +function. */ +static xTimerHandle xLEDTimer = NULL; + +/* The check timer. This uses vCheckTimerCallback() as it's callback +function. */ +static xTimerHandle xCheckTimer = NULL; + +/* The OLED software timer. Writes a moving text string to the OLED. */ +static xTimerHandle xOLEDTimer = NULL; + +/* The status message that is displayed at the bottom of the "task stats" web +page, which is served by the uIP task. This will report any errors picked up +by the check timer callback. */ +static const char *pcStatusMessage = NULL; + +/*-----------------------------------------------------------*/ + +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 application specific demo 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. */ + ); + + /* Create the software timer that performs the 'check' functionality, + as described at the top of this file. */ + xCheckTimer = xTimerCreate( ( const signed char * ) "CheckTimer", /* A text name, purely to help debugging. */ + ( mainCHECK_TIMER_PERIOD_ms / portTICK_RATE_MS ),/* The timer period, in this case 3000ms (3s). */ + pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */ + ( void * ) 0, /* The ID is not used, so can be set to anything. */ + vCheckTimerCallback /* The callback function that inspects the status of all the other tasks. */ + ); + + /* Create the OLED timer as described at the top of this file. */ + xOLEDTimer = xTimerCreate( ( const signed char * ) "OLEDTimer", ( mainOLED_PERIOD_ms / portTICK_RATE_MS ), pdTRUE, ( void * ) 0, vOLEDTimerCallback ); + + /* Create a lot of 'standard demo' tasks. */ + vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); + vCreateBlockTimeTasks(); + vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); + vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY ); + vStartLEDFlashTasks( mainFLASH_TASK_PRIORITY ); + vStartQueuePeekTasks(); + vStartRecursiveMutexTasks(); + vStartTimerDemoTask( mainTIMER_TEST_PERIOD ); + + /* Create the web server task. */ +// xTaskCreate( vuIP_Task, ( signed char * ) "uIP", mainuIP_STACK_SIZE, NULL, mainuIP_TASK_PRIORITY, NULL ); + + /* 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 vCheckTimerCallback( xTimerHandle xTimer ) +{ + /* Check the standard demo tasks are running without error. Latch the + latest reported error in the pcStatusMessage character pointer. */ + if( xAreGenericQueueTasksStillRunning() != pdTRUE ) + { + pcStatusMessage = "Error: GenQueue"; + } + + if( xAreQueuePeekTasksStillRunning() != pdTRUE ) + { + pcStatusMessage = "Error: QueuePeek\r\n"; + } + + if( xAreBlockingQueuesStillRunning() != pdTRUE ) + { + pcStatusMessage = "Error: BlockQueue\r\n"; + } + + if( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) + { + pcStatusMessage = "Error: BlockTime\r\n"; + } + + if( xAreSemaphoreTasksStillRunning() != pdTRUE ) + { + pcStatusMessage = "Error: SemTest\r\n"; + } + + if( xIsCreateTaskStillRunning() != pdTRUE ) + { + pcStatusMessage = "Error: Death\r\n"; + } + + if( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) + { + pcStatusMessage = "Error: RecMutex\r\n"; + } + + if( xAreTimerDemoTasksStillRunning( ( mainCHECK_TIMER_PERIOD_ms / portTICK_RATE_MS ) ) != pdTRUE ) + { + pcStatusMessage = "Error: TimerDemo"; + } + + /* Toggle the check LED to give an indication of the system status. If + the LED toggles every mainCHECK_TIMER_PERIOD_ms milliseconds then + everything is ok. A faster toggle indicates an error. */ + vParTestToggleLED( mainCHECK_LED ); + + /* Have any errors been latch in pcStatusMessage? If so, shorten the + period of the check timer to mainERROR_CHECK_TIMER_PERIOD_ms milliseconds. + This will result in an increase in the rate at which mainCHECK_LED + toggles. */ + if( pcStatusMessage != NULL ) + { + /* This call to xTimerChangePeriod() uses a zero block time. Functions + called from inside of a timer callback function must *never* attempt + to block. */ + xTimerChangePeriod( xCheckTimer, ( mainERROR_CHECK_TIMER_PERIOD_ms / portTICK_RATE_MS ), mainDONT_BLOCK ); + } +} +/*-----------------------------------------------------------*/ + +static void vLEDTimerCallback( xTimerHandle xTimer ) +{ + /* The timer has expired - so no button pushes have occurred in the last + five seconds - turn the LED off. */ + vParTestSetLED( mainTIMER_CONTROLLED_LED, pdFALSE ); +} +/*-----------------------------------------------------------*/ + +/* 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. */ + vParTestSetLEDFromISR( mainTIMER_CONTROLLED_LED, pdTRUE ); + + /* 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; + + /* The suicide tasks must be created last, as they need to know how many + tasks were running prior to their creation in order to ascertain whether + or not the correct/expected number of tasks are running at any given time. + Therefore the standard demo 'death' tasks are not created in main(), but + instead created here. */ + vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY ); + + /* The timer command queue will have been filled when the timer test tasks + were created in main() (this is part of the test they perform). Therefore, + while the check and OLED timers can be created in main(), they cannot be + started from main(). Once the scheduler has started, the timer service + task will drain the command queue, and now the check and OLED timers can be + started successfully. */ + xTimerStart( xCheckTimer, portMAX_DELAY ); + xTimerStart( xOLEDTimer, portMAX_DELAY ); + + /* 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 LED. */ + if( ulReceivedValue == 100UL ) + { + vParTestToggleLED( mainTASK_CONTROLLED_LED ); + } + } +} +/*-----------------------------------------------------------*/ + +static void vOLEDTimerCallback( xTimerHandle xHandle ) +{ +volatile size_t xFreeStackSpace; +static struct oled_data xOLEDData; +static unsigned char ucOffset1 = 0, ucOffset2 = 5; + + /* This function is called on each cycle of the idle task. In this case it + does nothing useful, other than report the amount 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. */ + } + + xOLEDData.line1 = FIRST_LINE; + xOLEDData.char_offset1 = ucOffset1++; + xOLEDData.string1 = "www.FreeRTOS.org"; + + xOLEDData.line2 = SECOND_LINE; + xOLEDData.char_offset2 = ucOffset2++; + xOLEDData.string2 = "www.FreeRTOS.org"; + + xOLEDData.contrast_val = OLED_CONTRAST_VAL; + xOLEDData.on_off = OLED_HORIZ_SCROLL_OFF; + xOLEDData.column_scrool_per_step = OLED_HORIZ_SCROLL_STEP; + xOLEDData.start_page = OLED_START_PAGE; + xOLEDData.time_intrval_btw_scroll_step = OLED_HORIZ_SCROLL_TINVL; + xOLEDData.end_page = OLED_END_PAGE; + + OLED_write_data( &xOLEDData, BOTH_LINES ); +} +/*-----------------------------------------------------------*/ + +static void prvSetupHardware( void ) +{ + /* Disable the Watch Dog Timer */ + MSS_WD_disable( ); + + /* Configure the GPIO for the LEDs. */ + vParTestInitialise(); + + /* Initialise the display. */ + OLED_init(); + + /* Setup the GPIO and the NVIC for the switch used in this simple demo. */ + NVIC_SetPriority( GPIO8_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); + 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. */ + taskDISABLE_INTERRUPTS(); + 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 amount 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. */ + } +} +/*-----------------------------------------------------------*/ + +char *pcGetTaskStatusMessage( void ) +{ + /* Not bothered about a critical section here although technically because + of the task priorities the pointer could change it will be atomic if not + near atomic and its not critical. */ + if( pcStatusMessage == NULL ) + { + return "All tasks running without error"; + } + else + { + return ( char * ) pcStatusMessage; + } +} +/*-----------------------------------------------------------*/ + diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/printf-stdarg.c b/Demo/CORTEX_A2F200_IAR_and_Keil/printf-stdarg.c new file mode 100644 index 000000000..b5ac41be7 --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/printf-stdarg.c @@ -0,0 +1,293 @@ +/* + Copyright 2001, 2002 Georges Menie (www.menie.org) + stdarg version contributed by Christian Ettinger + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* + putchar is the only external dependency for this file, + if you have a working putchar, leave it commented out. + If not, uncomment the define below and + replace outbyte(c) by your own function call. + +*/ + +#define putchar(c) c + +#include + +static void printchar(char **str, int c) +{ + //extern int putchar(int c); + + if (str) { + **str = (char)c; + ++(*str); + } + else + { + (void)putchar(c); + } +} + +#define PAD_RIGHT 1 +#define PAD_ZERO 2 + +static int prints(char **out, const char *string, int width, int pad) +{ + register int pc = 0, padchar = ' '; + + if (width > 0) { + register int len = 0; + register const char *ptr; + for (ptr = string; *ptr; ++ptr) ++len; + if (len >= width) width = 0; + else width -= len; + if (pad & PAD_ZERO) padchar = '0'; + } + if (!(pad & PAD_RIGHT)) { + for ( ; width > 0; --width) { + printchar (out, padchar); + ++pc; + } + } + for ( ; *string ; ++string) { + printchar (out, *string); + ++pc; + } + for ( ; width > 0; --width) { + printchar (out, padchar); + ++pc; + } + + return pc; +} + +/* the following should be enough for 32 bit int */ +#define PRINT_BUF_LEN 12 + +static int printi(char **out, int i, int b, int sg, int width, int pad, int letbase) +{ + char print_buf[PRINT_BUF_LEN]; + register char *s; + register int t, neg = 0, pc = 0; + register unsigned int u = (unsigned int)i; + + if (i == 0) { + print_buf[0] = '0'; + print_buf[1] = '\0'; + return prints (out, print_buf, width, pad); + } + + if (sg && b == 10 && i < 0) { + neg = 1; + u = (unsigned int)-i; + } + + s = print_buf + PRINT_BUF_LEN-1; + *s = '\0'; + + while (u) { + t = (unsigned int)u % b; + if( t >= 10 ) + t += letbase - '0' - 10; + *--s = (char)(t + '0'); + u /= b; + } + + if (neg) { + if( width && (pad & PAD_ZERO) ) { + printchar (out, '-'); + ++pc; + --width; + } + else { + *--s = '-'; + } + } + + return pc + prints (out, s, width, pad); +} + +static int print( char **out, const char *format, va_list args ) +{ + register int width, pad; + register int pc = 0; + char scr[2]; + + for (; *format != 0; ++format) { + if (*format == '%') { + ++format; + width = pad = 0; + if (*format == '\0') break; + if (*format == '%') goto out; + if (*format == '-') { + ++format; + pad = PAD_RIGHT; + } + while (*format == '0') { + ++format; + pad |= PAD_ZERO; + } + for ( ; *format >= '0' && *format <= '9'; ++format) { + width *= 10; + width += *format - '0'; + } + if( *format == 's' ) { + register char *s = (char *)va_arg( args, int ); + pc += prints (out, s?s:"(null)", width, pad); + continue; + } + if( *format == 'd' ) { + pc += printi (out, va_arg( args, int ), 10, 1, width, pad, 'a'); + continue; + } + if( *format == 'x' ) { + pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'a'); + continue; + } + if( *format == 'X' ) { + pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'A'); + continue; + } + if( *format == 'u' ) { + pc += printi (out, va_arg( args, int ), 10, 0, width, pad, 'a'); + continue; + } + if( *format == 'c' ) { + /* char are converted to int then pushed on the stack */ + scr[0] = (char)va_arg( args, int ); + scr[1] = '\0'; + pc += prints (out, scr, width, pad); + continue; + } + } + else { + out: + printchar (out, *format); + ++pc; + } + } + if (out) **out = '\0'; + va_end( args ); + return pc; +} + +int printf(const char *format, ...) +{ + va_list args; + + va_start( args, format ); + return print( 0, format, args ); +} + +int sprintf(char *out, const char *format, ...) +{ + va_list args; + + va_start( args, format ); + return print( &out, format, args ); +} + + +int snprintf( char *buf, unsigned int count, const char *format, ... ) +{ + va_list args; + + ( void ) count; + + va_start( args, format ); + return print( &buf, format, args ); +} + + +#ifdef TEST_PRINTF +int main(void) +{ + char *ptr = "Hello world!"; + char *np = 0; + int i = 5; + unsigned int bs = sizeof(int)*8; + int mi; + char buf[80]; + + mi = (1 << (bs-1)) + 1; + printf("%s\n", ptr); + printf("printf test\n"); + printf("%s is null pointer\n", np); + printf("%d = 5\n", i); + printf("%d = - max int\n", mi); + printf("char %c = 'a'\n", 'a'); + printf("hex %x = ff\n", 0xff); + printf("hex %02x = 00\n", 0); + printf("signed %d = unsigned %u = hex %x\n", -3, -3, -3); + printf("%d %s(s)%", 0, "message"); + printf("\n"); + printf("%d %s(s) with %%\n", 0, "message"); + sprintf(buf, "justif: \"%-10s\"\n", "left"); printf("%s", buf); + sprintf(buf, "justif: \"%10s\"\n", "right"); printf("%s", buf); + sprintf(buf, " 3: %04d zero padded\n", 3); printf("%s", buf); + sprintf(buf, " 3: %-4d left justif.\n", 3); printf("%s", buf); + sprintf(buf, " 3: %4d right justif.\n", 3); printf("%s", buf); + sprintf(buf, "-3: %04d zero padded\n", -3); printf("%s", buf); + sprintf(buf, "-3: %-4d left justif.\n", -3); printf("%s", buf); + sprintf(buf, "-3: %4d right justif.\n", -3); printf("%s", buf); + + return 0; +} + +/* + * if you compile this file with + * gcc -Wall $(YOUR_C_OPTIONS) -DTEST_PRINTF -c printf.c + * you will get a normal warning: + * printf.c:214: warning: spurious trailing `%' in format + * this line is testing an invalid % at the end of the format string. + * + * this should display (on 32bit int machine) : + * + * Hello world! + * printf test + * (null) is null pointer + * 5 = 5 + * -2147483647 = - max int + * char a = 'a' + * hex ff = ff + * hex 00 = 00 + * signed -3 = unsigned 4294967293 = hex fffffffd + * 0 message(s) + * 0 message(s) with % + * justif: "left " + * justif: " right" + * 3: 0003 zero padded + * 3: 3 left justif. + * 3: 3 right justif. + * -3: -003 zero padded + * -3: -3 left justif. + * -3: -3 right justif. + */ + +#endif + + +/* To keep linker happy. */ +int write( int i, char* c, int n) +{ + (void)i; + (void)n; + (void)c; + return 0; +} + diff --git a/Demo/CORTEX_A2F200_IAR_and_Keil/uIP_Task.c b/Demo/CORTEX_A2F200_IAR_and_Keil/uIP_Task.c new file mode 100644 index 000000000..bc7ad544e --- /dev/null +++ b/Demo/CORTEX_A2F200_IAR_and_Keil/uIP_Task.c @@ -0,0 +1,449 @@ +unsigned long ulRxed = 0, ulRxISR = 0, ulTxed = 0, ulTxISR = 0; +/* + FreeRTOS V7.0.0 - Copyright (C) 2011 Real Time Engineers Ltd. + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and 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 modification 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. +*/ + +/* Standard includes. */ +#include + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" + +/* uip includes. */ +#include "net/uip.h" +#include "net/uip_arp.h" +#include "apps/httpd/httpd.h" +#include "sys/timer.h" +#include "net/clock-arch.h" + +/* Demo includes. */ +#include "ParTest.h" + +/* Hardware driver includes. */ +#include "mss_ethernet_mac_regs.h" +#include "mss_ethernet_mac.h" + +/* The buffer used by the uIP stack to both receive and send. This points to +one of the Ethernet buffers when its actually in use. */ +extern unsigned char *uip_buf; + +static const unsigned char ucMACAddress[] = { configMAC_ADDR0, configMAC_ADDR1, configMAC_ADDR2, configMAC_ADDR3, configMAC_ADDR4, configMAC_ADDR5 }; + +#define uipARP_TIMER 0 +#define uipPERIODIC_TIMER 1 + +#define uipEVENT_QUEUE_LENGTH 10 + +#define uipETHERNET_RX_EVENT 0x01UL +#define uipETHERNET_TX_EVENT 0x02UL +#define uipARP_TIMER_EVENT 0x04UL +#define uipPERIODIC_TIMER_EVENT 0x08UL +#define uipAPPLICATION_SEND_EVENT 0x10UL + +#define uipDONT_BLOCK 0UL + +/*-----------------------------------------------------------*/ + +/* How long to wait before attempting to connect the MAC again. */ +#define uipINIT_WAIT ( 100 / portTICK_RATE_MS ) + +/* Shortcut to the header within the Rx buffer. */ +#define xHeader ((struct uip_eth_hdr *) &uip_buf[ 0 ]) + +/* Standard constant. */ +#define uipTOTAL_FRAME_HEADER_SIZE 54 + +/*-----------------------------------------------------------*/ + +/* + * Setup the MAC address in the MAC itself, and in the uIP stack. + */ +static void prvSetMACAddress( void ); + +/* + * Perform any uIP initialisation required to ready the stack for http + * processing. + */ +static void prvInitialise_uIP( void ); + +/* + * Handles Ethernet interrupt events. + */ +static void prvEMACEventListener( unsigned long ulISREvents ); + +static void prvUIPTimerCallback( xTimerHandle xTimer ); + +/* + * Initialise the MAC hardware. + */ +static void prvInitEmac( void ); + +void vEMACWrite( void ); + +long lEMACWaitForLink( void ); + +/* + * Port functions required by the uIP stack. + */ +void clock_init( void ); +clock_time_t clock_time( void ); + +/*-----------------------------------------------------------*/ + +/* The queue used to send TCP/IP events to the uIP stack. */ +xQueueHandle xEMACEventQueue = NULL; + +static unsigned long ulUIP_Events = 0UL; + +/*-----------------------------------------------------------*/ + +void clock_init(void) +{ + /* This is done when the scheduler starts. */ +} +/*-----------------------------------------------------------*/ + +clock_time_t clock_time( void ) +{ + return xTaskGetTickCount(); +} +/*-----------------------------------------------------------*/ + +void vuIP_Task( void *pvParameters ) +{ +portBASE_TYPE i; +unsigned long ulNewEvent; + + ( void ) pvParameters; + + /* Initialise the uIP stack, configuring for web server usage. */ + prvInitialise_uIP(); + + /* Initialise the MAC. */ + prvInitEmac(); + + for( ;; ) + { + if( ( ulUIP_Events & uipETHERNET_RX_EVENT ) != 0UL ) + { + ulUIP_Events &= ~uipETHERNET_RX_EVENT; + + /* Is there received data ready to be processed? */ + uip_len = MSS_MAC_rx_packet(); + + if( ( uip_len > 0 ) && ( uip_buf != NULL ) ) + { + ulRxed++; + /* Standard uIP loop taken from the uIP manual. */ + if( xHeader->type == htons( UIP_ETHTYPE_IP ) ) + { + uip_arp_ipin(); + uip_input(); + + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if( uip_len > 0 ) + { + uip_arp_out(); + vEMACWrite(); + } + } + else if( xHeader->type == htons( UIP_ETHTYPE_ARP ) ) + { + uip_arp_arpin(); + + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if( uip_len > 0 ) + { + vEMACWrite(); + } + } + } + } + + if( ( ulUIP_Events & uipPERIODIC_TIMER_EVENT ) != 0UL ) + { + ulUIP_Events &= ~uipPERIODIC_TIMER_EVENT; + + for( i = 0; i < UIP_CONNS; i++ ) + { + uip_periodic( i ); + + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if( uip_len > 0 ) + { + uip_arp_out(); + vEMACWrite(); + } + } + } + + /* Call the ARP timer function every 10 seconds. */ + if( ( ulUIP_Events & uipARP_TIMER_EVENT ) != 0 ) + { + ulUIP_Events &= ~uipARP_TIMER_EVENT; + uip_arp_timer(); + } + + if( ulUIP_Events == pdFALSE ) + { + xQueueReceive( xEMACEventQueue, &ulNewEvent, portMAX_DELAY ); + ulUIP_Events |= ulNewEvent; + } + } +} +/*-----------------------------------------------------------*/ + +static void prvSetMACAddress( void ) +{ +struct uip_eth_addr xAddr; + + /* Configure the MAC address in the uIP stack. */ + xAddr.addr[ 0 ] = configMAC_ADDR0; + xAddr.addr[ 1 ] = configMAC_ADDR1; + xAddr.addr[ 2 ] = configMAC_ADDR2; + xAddr.addr[ 3 ] = configMAC_ADDR3; + xAddr.addr[ 4 ] = configMAC_ADDR4; + xAddr.addr[ 5 ] = configMAC_ADDR5; + uip_setethaddr( xAddr ); +} +/*-----------------------------------------------------------*/ + +void vApplicationProcessFormInput( char *pcInputString ) +{ +char *c; + + /* Only interested in processing form input if this is the IO page. */ + c = strstr( pcInputString, "io.shtml" ); + + if( c ) + { + /* Is there a command in the string? */ + c = strstr( pcInputString, "?" ); + if( c ) + { + /* Turn the LED's on or off in accordance with the check box status. */ + if( strstr( c, "LED0=1" ) != NULL ) + { + /* Turn the LEDs on. */ + vParTestSetLED( 7, 1 ); + vParTestSetLED( 8, 1 ); + vParTestSetLED( 9, 1 ); + vParTestSetLED( 10, 1 ); + } + else + { + /* Turn the LEDs off. */ + vParTestSetLED( 7, 0 ); + vParTestSetLED( 8, 0 ); + vParTestSetLED( 9, 0 ); + vParTestSetLED( 10, 0 ); + } + } + else + { + /* Commands to turn LEDs off are not always explicit. */ + vParTestSetLED( 7, 0 ); + vParTestSetLED( 8, 0 ); + vParTestSetLED( 9, 0 ); + vParTestSetLED( 10, 0 ); + } + } +} +/*-----------------------------------------------------------*/ + +static void prvInitialise_uIP( void ) +{ +uip_ipaddr_t xIPAddr; +xTimerHandle xARPTimer, xPeriodicTimer; + + uip_init(); + uip_ipaddr( &xIPAddr, configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 ); + uip_sethostaddr( &xIPAddr ); + uip_ipaddr( &xIPAddr, configNET_MASK0, configNET_MASK1, configNET_MASK2, configNET_MASK3 ); + uip_setnetmask( &xIPAddr ); + prvSetMACAddress(); + httpd_init(); + + /* Create the queue used to sent TCP/IP events to the uIP stack. */ + xEMACEventQueue = xQueueCreate( uipEVENT_QUEUE_LENGTH, sizeof( unsigned long ) ); + + /* Create and start the uIP timers. */ + xARPTimer = xTimerCreate( ( const signed char * const ) "ARPTimer", /* Just a name that is helpful for debugging, not used by the kernel. */ + ( 500 / portTICK_RATE_MS ), /* Timer period. */ + pdTRUE, /* Autor-reload. */ + ( void * ) uipARP_TIMER, + prvUIPTimerCallback + ); + + xPeriodicTimer = xTimerCreate( ( const signed char * const ) "PeriodicTimer", + ( 5000 / portTICK_RATE_MS ), + pdTRUE, /* Autor-reload. */ + ( void * ) uipPERIODIC_TIMER, + prvUIPTimerCallback + ); + + configASSERT( xARPTimer ); + configASSERT( xPeriodicTimer ); + + xTimerStart( xARPTimer, portMAX_DELAY ); + xTimerStart( xPeriodicTimer, portMAX_DELAY ); +} +/*-----------------------------------------------------------*/ + +static void prvEMACEventListener( unsigned long ulISREvents ) +{ +long lHigherPriorityTaskWoken = pdFALSE; +unsigned long ulUIPEvents = 0UL; + + configASSERT( xEMACEventQueue ); + + if( ( ulISREvents & MSS_MAC_EVENT_PACKET_SEND ) != 0UL ) + { + ulTxISR++; + MSS_MAC_TxBufferCompleted(); + } + + if( ( ulISREvents & MSS_MAC_EVENT_PACKET_RECEIVED ) != 0UL ) + { + ulRxISR++; + /* Wake the uIP task as new data has arrived. */ + ulUIPEvents |= uipETHERNET_RX_EVENT; + } + + if( ulUIPEvents != 0UL ) + { + xQueueSendFromISR( xEMACEventQueue, &ulUIPEvents, &lHigherPriorityTaskWoken ); + } + + portEND_SWITCHING_ISR( lHigherPriorityTaskWoken ); +} +/*-----------------------------------------------------------*/ + +static void prvInitEmac( void ) +{ +const unsigned char ucPHYAddress = 1; + + MSS_MAC_init( ucPHYAddress ); + + MSS_MAC_set_callback( prvEMACEventListener ); + + /* Setup the EMAC and the NVIC for MAC interrupts. */ + NVIC_SetPriority( EthernetMAC_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); + NVIC_EnableIRQ( EthernetMAC_IRQn ); +} +/*-----------------------------------------------------------*/ + +void vEMACWrite( void ) +{ +const long lMaxAttempts = 10; +long lAttempt; +const portTickType xShortDelay = ( 10 / portTICK_RATE_MS ); + + for( lAttempt = 0; lAttempt < lMaxAttempts; lAttempt++ ) + { + if( MSS_MAC_tx_packet( uip_len ) != 0 ) + { + ulTxed++; + break; + } + else + { + vTaskDelay( xShortDelay ); + } + } +} +/*-----------------------------------------------------------*/ + +long lEMACWaitForLink( void ) +{ +long lReturn = pdFAIL; +unsigned long ulStatus; + + ulStatus = MSS_MAC_link_status(); + if( ( ulStatus & ( unsigned long ) MSS_MAC_LINK_STATUS_LINK ) != 0UL ) + { + lReturn = pdPASS; + } + + return lReturn; +} +/*-----------------------------------------------------------*/ + +static void prvUIPTimerCallback( xTimerHandle xTimer ) +{ +static const unsigned long ulARPTimerExpired = uipARP_TIMER_EVENT; +static const unsigned long ulPeriodicTimerExpired = uipPERIODIC_TIMER_EVENT; + + /* This is a time callback, so calls to xQueueSend() must not attempt to + block. */ + switch( ( int ) pvTimerGetTimerID( xTimer ) ) + { + case uipARP_TIMER : xQueueSend( xEMACEventQueue, &ulARPTimerExpired, uipDONT_BLOCK ); + break; + + case uipPERIODIC_TIMER : xQueueSend( xEMACEventQueue, &ulPeriodicTimerExpired, uipDONT_BLOCK ); + break; + + default : /* Should not get here. */ + break; + } +} +/*-----------------------------------------------------------*/ -- 2.39.2
LocalRemoteStateRetransmissionsTimerFlags