From e3b8e6363c923bea6609dad27b87cba23a4c8521 Mon Sep 17 00:00:00 2001 From: richardbarry Date: Thu, 8 Feb 2007 06:34:35 +0000 Subject: [PATCH] GCC demo for the LM3S811 eval board from Luminary Micro. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@63 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- Demo/CORTEX_LM3S811_GCC/FreeRTOSConfig.h | 76 + Demo/CORTEX_LM3S811_GCC/Makefile | 85 + .../CORTEX_LM3S811_GCC/hw_include/DriverLib.h | 39 + Demo/CORTEX_LM3S811_GCC/hw_include/EULA.txt | 126 ++ Demo/CORTEX_LM3S811_GCC/hw_include/adc.c | 946 +++++++++ Demo/CORTEX_LM3S811_GCC/hw_include/adc.h | 126 ++ Demo/CORTEX_LM3S811_GCC/hw_include/comp.c | 448 ++++ Demo/CORTEX_LM3S811_GCC/hw_include/comp.h | 120 ++ Demo/CORTEX_LM3S811_GCC/hw_include/cpu.h | 40 + Demo/CORTEX_LM3S811_GCC/hw_include/debug.h | 56 + .../hw_include/driverlib.r79 | Bin 0 -> 134217 bytes Demo/CORTEX_LM3S811_GCC/hw_include/flash.c | 668 ++++++ Demo/CORTEX_LM3S811_GCC/hw_include/flash.h | 75 + Demo/CORTEX_LM3S811_GCC/hw_include/gpio.c | 1103 ++++++++++ Demo/CORTEX_LM3S811_GCC/hw_include/gpio.h | 137 ++ Demo/CORTEX_LM3S811_GCC/hw_include/hw_adc.h | 343 +++ Demo/CORTEX_LM3S811_GCC/hw_include/hw_comp.h | 118 + Demo/CORTEX_LM3S811_GCC/hw_include/hw_flash.h | 139 ++ Demo/CORTEX_LM3S811_GCC/hw_include/hw_gpio.h | 103 + Demo/CORTEX_LM3S811_GCC/hw_include/hw_i2c.h | 197 ++ Demo/CORTEX_LM3S811_GCC/hw_include/hw_ints.h | 97 + .../CORTEX_LM3S811_GCC/hw_include/hw_memmap.h | 64 + Demo/CORTEX_LM3S811_GCC/hw_include/hw_nvic.h | 830 ++++++++ Demo/CORTEX_LM3S811_GCC/hw_include/hw_pwm.h | 260 +++ Demo/CORTEX_LM3S811_GCC/hw_include/hw_qei.h | 176 ++ Demo/CORTEX_LM3S811_GCC/hw_include/hw_ssi.h | 120 ++ .../CORTEX_LM3S811_GCC/hw_include/hw_sysctl.h | 409 ++++ Demo/CORTEX_LM3S811_GCC/hw_include/hw_timer.h | 235 ++ Demo/CORTEX_LM3S811_GCC/hw_include/hw_types.h | 67 + Demo/CORTEX_LM3S811_GCC/hw_include/hw_uart.h | 239 +++ .../hw_include/hw_watchdog.h | 116 + Demo/CORTEX_LM3S811_GCC/hw_include/i2c.c | 972 +++++++++ Demo/CORTEX_LM3S811_GCC/hw_include/i2c.h | 137 ++ .../CORTEX_LM3S811_GCC/hw_include/interrupt.c | 552 +++++ .../CORTEX_LM3S811_GCC/hw_include/interrupt.h | 57 + .../CORTEX_LM3S811_GCC/hw_include/libdriver.a | Bin 0 -> 246310 bytes .../hw_include/osram96x16.c | 975 +++++++++ .../hw_include/osram96x16.h | 47 + Demo/CORTEX_LM3S811_GCC/hw_include/pwm.c | 1291 +++++++++++ Demo/CORTEX_LM3S811_GCC/hw_include/pwm.h | 161 ++ Demo/CORTEX_LM3S811_GCC/hw_include/qei.c | 630 ++++++ Demo/CORTEX_LM3S811_GCC/hw_include/qei.h | 104 + Demo/CORTEX_LM3S811_GCC/hw_include/ssi.c | 609 ++++++ Demo/CORTEX_LM3S811_GCC/hw_include/ssi.h | 89 + Demo/CORTEX_LM3S811_GCC/hw_include/sysctl.c | 1889 +++++++++++++++++ Demo/CORTEX_LM3S811_GCC/hw_include/sysctl.h | 285 +++ Demo/CORTEX_LM3S811_GCC/hw_include/systick.c | 262 +++ Demo/CORTEX_LM3S811_GCC/hw_include/systick.h | 55 + Demo/CORTEX_LM3S811_GCC/hw_include/timer.c | 1125 ++++++++++ Demo/CORTEX_LM3S811_GCC/hw_include/timer.h | 137 ++ Demo/CORTEX_LM3S811_GCC/hw_include/uart.c | 821 +++++++ Demo/CORTEX_LM3S811_GCC/hw_include/uart.h | 102 + Demo/CORTEX_LM3S811_GCC/hw_include/watchdog.c | 592 ++++++ Demo/CORTEX_LM3S811_GCC/hw_include/watchdog.h | 63 + Demo/CORTEX_LM3S811_GCC/init/startup.c | 221 ++ Demo/CORTEX_LM3S811_GCC/main.c | 362 ++++ Demo/CORTEX_LM3S811_GCC/makedefs | 208 ++ Demo/CORTEX_LM3S811_GCC/standalone.ld | 60 + 58 files changed, 19364 insertions(+) create mode 100644 Demo/CORTEX_LM3S811_GCC/FreeRTOSConfig.h create mode 100644 Demo/CORTEX_LM3S811_GCC/Makefile create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/DriverLib.h create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/EULA.txt create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/adc.c create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/adc.h create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/comp.c create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/comp.h create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/cpu.h create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/debug.h create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/driverlib.r79 create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/flash.c create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/flash.h create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/gpio.c create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/gpio.h create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/hw_adc.h create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/hw_comp.h create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/hw_flash.h create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/hw_gpio.h create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/hw_i2c.h create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/hw_ints.h create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/hw_memmap.h create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/hw_nvic.h create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/hw_pwm.h create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/hw_qei.h create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/hw_ssi.h create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/hw_sysctl.h create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/hw_timer.h create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/hw_types.h create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/hw_uart.h create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/hw_watchdog.h create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/i2c.c create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/i2c.h create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/interrupt.c create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/interrupt.h create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/libdriver.a create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/osram96x16.c create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/osram96x16.h create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/pwm.c create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/pwm.h create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/qei.c create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/qei.h create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/ssi.c create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/ssi.h create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/sysctl.c create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/sysctl.h create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/systick.c create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/systick.h create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/timer.c create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/timer.h create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/uart.c create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/uart.h create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/watchdog.c create mode 100644 Demo/CORTEX_LM3S811_GCC/hw_include/watchdog.h create mode 100644 Demo/CORTEX_LM3S811_GCC/init/startup.c create mode 100644 Demo/CORTEX_LM3S811_GCC/main.c create mode 100644 Demo/CORTEX_LM3S811_GCC/makedefs create mode 100644 Demo/CORTEX_LM3S811_GCC/standalone.ld diff --git a/Demo/CORTEX_LM3S811_GCC/FreeRTOSConfig.h b/Demo/CORTEX_LM3S811_GCC/FreeRTOSConfig.h new file mode 100644 index 000000000..fdb0f2b3e --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/FreeRTOSConfig.h @@ -0,0 +1,76 @@ +/* + FreeRTOS.org V4.1.3 - Copyright (C) 2003-2006 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + FreeRTOS.org 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 + along with FreeRTOS.org; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + A special exception to the GPL can be applied should you wish to distribute + a combined work that includes FreeRTOS.org, without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details of how and when the exception + can be applied. + + *************************************************************************** + See http://www.FreeRTOS.org for documentation, latest information, license + and contact details. Please ensure to read the configuration and relevant + port sections of the online documentation. + *************************************************************************** +*/ + +#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. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configCPU_CLOCK_HZ ( ( unsigned portLONG ) 20000000 ) +#define configTICK_RATE_HZ ( ( portTickType ) 1000 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 70 ) +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 7000 ) ) +#define configMAX_TASK_NAME_LEN ( 10 ) +#define configUSE_TRACE_FACILITY 0 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 0 +#define configUSE_CO_ROUTINES 0 + +#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 5 ) +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +/* Set the following definitions to 1 to include the API function, or zero +to exclude the API function. */ + +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 + + + + +#endif /* FREERTOS_CONFIG_H */ diff --git a/Demo/CORTEX_LM3S811_GCC/Makefile b/Demo/CORTEX_LM3S811_GCC/Makefile new file mode 100644 index 000000000..814cc6f7e --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/Makefile @@ -0,0 +1,85 @@ +#****************************************************************************** +# +# Makefile - Rules for building the driver library and examples. +# +# Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +# +# Software License Agreement +# +# Luminary Micro, Inc. (LMI) is supplying this software for use solely and +# exclusively on LMI's Stellaris Family of microcontroller products. +# +# The software is owned by LMI and/or its suppliers, and is protected under +# applicable copyright laws. All rights are reserved. Any use in violation +# of the foregoing restrictions may subject the user to criminal sanctions +# under applicable laws, as well as to civil liability for the breach of the +# terms and conditions of this license. +# +# 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. +# LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +# CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +# +#****************************************************************************** + +include makedefs + +RTOS_SOURCE_DIR=../../Source +DEMO_SOURCE_DIR=../Common/Minimal + +CFLAGS+=-I hw_include -I . -I ${RTOS_SOURCE_DIR}/include -I ${RTOS_SOURCE_DIR}/portable/GCC/ARM_CM3 -I ../Common/include -D GCC_ARMCM3_LM3S102 -D inline= + +VPATH=${RTOS_SOURCE_DIR}:${RTOS_SOURCE_DIR}/portable/MemMang:${RTOS_SOURCE_DIR}/portable/GCC/ARM_CM3:${DEMO_SOURCE_DIR}:init:hw_include + +OBJS=${COMPILER}/main.o \ + ${COMPILER}/list.o \ + ${COMPILER}/queue.o \ + ${COMPILER}/tasks.o \ + ${COMPILER}/port.o \ + ${COMPILER}/heap_1.o \ + ${COMPILER}/BlockQ.o \ + ${COMPILER}/PollQ.o \ + ${COMPILER}/integer.o \ + ${COMPILER}/semtest.o \ + ${COMPILER}/osram96x16.o + +INIT_OBJS= ${COMPILER}/startup.o + +LIBS= hw_include/libdriver.a + + +# +# The default rule, which causes init to be built. +# +all: ${COMPILER} \ + ${COMPILER}/RTOSDemo.axf \ + +# +# The rule to clean out all the build products +# + +clean: + @rm -rf ${COMPILER} ${wildcard *.bin} RTOSDemo.axf + +# +# The rule to create the target directory +# +${COMPILER}: + @mkdir ${COMPILER} + +${COMPILER}/RTOSDemo.axf: ${INIT_OBJS} ${OBJS} ${LIBS} +SCATTER_RTOSDemo=standalone.ld +ENTRY_RTOSDemo=ResetISR + +# +# +# Include the automatically generated dependency files. +# +-include ${wildcard ${COMPILER}/*.d} __dummy__ + + + + + + diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/DriverLib.h b/Demo/CORTEX_LM3S811_GCC/hw_include/DriverLib.h new file mode 100644 index 000000000..47531fbe9 --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/DriverLib.h @@ -0,0 +1,39 @@ +#ifndef DRIVER_LIB_H +#define DRIVER_LIB_H + +#include "DriverLib.h" +#include "hw_adc.h" +#include "hw_comp.h" +#include "hw_flash.h" +#include "hw_gpio.h" +#include "hw_i2c.h" +#include "hw_ints.h" +#include "hw_memmap.h" +#include "hw_nvic.h" +#include "hw_pwm.h" +#include "hw_qei.h" +#include "hw_ssi.h" +#include "hw_sysctl.h" +#include "hw_timer.h" +#include "hw_types.h" +#include "hw_uart.h" +#include "hw_watchdog.h" +#include "osram96x16.h" +#include "adc.h" +#include "comp.h" +#include "cpu.h" +#include "debug.h" +#include "flash.h" +#include "gpio.h" +#include "i2c.h" +#include "interrupt.h" +#include "pwm.h" +#include "qei.h" +#include "ssi.h" +#include "sysctl.h" +#include "systick.h" +#include "timer.h" +#include "uart.h" +#include "watchdog.h" + +#endif diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/EULA.txt b/Demo/CORTEX_LM3S811_GCC/hw_include/EULA.txt new file mode 100644 index 000000000..02c57b2f9 --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/EULA.txt @@ -0,0 +1,126 @@ +IMPORTANT. Read the following LMI Software License Agreement ("Agreement") +completely. + +LUMINARY MICRO SOFTWARE LICENSE AGREEMENT + + This is a legal agreement between you (either as an individual or as an +authorized representative of your employer) and Luminary Micro, Inc. ("LMI"). +It concerns your rights to use this file and any accompanying written materials +(the "Software"). In consideration for LMI allowing you to access the +Software, you are agreeing to be bound by the terms of this Agreement. If you +do not agree to all of the terms of this Agreement, do not download or use the +Software. If you change your mind later, stop using the Software and delete +all copies of the Software in your possession or control. Any copies of the +Software that you have already distributed, where permitted, and do not destroy +will continue to be governed by this Agreement. Your prior use will also +continue to be governed by this Agreement. + +1. LICENSE GRANT. LMI grants to you, free of charge, the non-exclusive, +non-transferable right (1) to use the Software, (2) to reproduce the Software, +(3) to prepare derivative works of the Software, (4) to distribute the Software +and derivative works thereof in source (human-readable) form and object +(machine-readable) form, and (5) to sublicense to others the right to use the +distributed Software. If you violate any of the terms or restrictions of this +Agreement, LMI may immediately terminate this Agreement, and require that you +stop using and delete all copies of the Software in your possession or control. + +2. COPYRIGHT. The Software is licensed to you, not sold. LMI owns the +Software, and United States copyright laws and international treaty provisions +protect the Software. Therefore, you must treat the Software like any other +copyrighted material (e.g. a book or musical recording). You may not use or +copy the Software for any other purpose than what is described in this +Agreement. Except as expressly provided herein, LMI does not grant to you any +express or implied rights under any LMI or third-party patents, copyrights, +trademarks, or trade secrets. Additionally, you must reproduce and apply any +copyright or other proprietary rights notices included on or embedded in the +Software to any copies or derivative works made thereof, in whole or in part, +if any. + +3. SUPPORT. LMI is NOT obligated to provide any support, upgrades or new +releases of the Software. If you wish, you may contact LMI and report problems +and provide suggestions regarding the Software. LMI has no obligation +whatsoever to respond in any way to such a problem report or suggestion. LMI +may make changes to the Software at any time, without any obligation to notify +or provide updated versions of the Software to you. + +4. INDEMNITY. You agree to fully defend and indemnify LMI from any and +all claims, liabilities, and costs (including reasonable attorney's fees) +related to (1) your use (including your sub-licensee's use, if permitted) of +the Software or (2) your violation of the terms and conditions of this +Agreement. + +5. HIGH RISK ACTIVITIES. You acknowledge that the Software is not fault +tolerant and is not designed, manufactured or intended by LMI for incorporation +into products intended for use or resale in on-line control equipment in +hazardous, dangerous to life or potentially life-threatening environments +requiring fail-safe performance, such as in the operation of nuclear +facilities, aircraft navigation or communication systems, air traffic control, +direct life support machines or weapons systems, in which the failure of +products could lead directly to death, personal injury or severe physical or +environmental damage ("High Risk Activities"). You specifically represent and +warrant that you will not use the Software or any derivative work of the +Software for High Risk Activities. + +6. PRODUCT LABELING. You are not authorized to use any LMI trademarks, +brand names, or logos. + +7. COMPLIANCE WITH LAWS; EXPORT RESTRICTIONS. You must use the Software +in accordance with all applicable U.S. laws, regulations and statutes. You +agree that neither you nor your licensees (if any) intend to or will, directly +or indirectly, export or transmit the Software to any country in violation of +U.S. export restrictions. + +8. GOVERNMENT USE. Use of the Software and any corresponding +documentation, if any, is provided with RESTRICTED RIGHTS. Use, duplication or +disclosure by the Government is subject to restrictions as set forth in +subparagraph (c)(1)(ii) of The Rights in Technical Data and Computer Software +clause at DFARS 252.227-7013 or subparagraphs (c)(l) and (2) of the Commercial +Computer Software--Restricted Rights at 48 CFR 52.227-19, as applicable. +Manufacturer is Luminary Micro, Inc., 2499 S. Capital of Texas Hwy Ste A-100, +Austin, Texas 78746. + +9. DISCLAIMER OF WARRANTY. TO THE MAXIMUM EXTENT PERMITTED BY LAW, LMI +EXPRESSLY DISCLAIMS ANY WARRANTY FOR THE SOFTWARE. THE SOFTWARE IS PROVIDED +"AS IS", WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, +WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE, OR NON-INFRINGEMENT. YOU ASSUME THE ENTIRE RISK ARISING +OUT OF THE USE OR PERFORMANCE OF THE SOFTWARE, OR ANY SYSTEMS YOU DESIGN USING +THE SOFTWARE (IF ANY). NOTHING IN THIS AGREEMENT MAY BE CONSTRUED AS A +WARRANTY OR REPRESENTATION BY LMI THAT THE SOFTWARE OR ANY DERIVATIVE WORK +DEVELOPED WITH OR INCORPORATING THE SOFTWARE WILL BE FREE FROM INFRINGEMENT OF +THE INTELLECTUAL PROPERTY RIGHTS OF THIRD PARTIES. + +10. LIMITATION OF LIABILITY. IN NO EVENT WILL LMI BE LIABLE, WHETHER IN +CONTRACT, TORT, OR OTHERWISE, FOR ANY INCIDENTAL, SPECIAL, INDIRECT, +CONSEQUENTIAL OR PUNITIVE DAMAGES, INCLUDING, BUT NOT LIMITED TO, DAMAGES FOR +ANY LOSS OF USE, LOSS OF TIME, INCONVENIENCE, COMMERCIAL LOSS, OR LOST PROFITS, +SAVINGS, OR REVENUES TO THE FULL EXTENT SUCH MAY BE DISCLAIMED BY LAW. + +11. CHOICE OF LAW; VENUE; LIMITATIONS. You agree that the statutes and +laws of the United States and the State of Texas, USA, without regard to +conflicts of laws principles, will apply to all matters relating to this +Agreement or the Software, and you agree that any litigation will be subject to +the exclusive jurisdiction of the state or federal courts in Austin, Travis +County, Texas, USA. You agree that regardless of any statute or law to the +contrary, any claim or cause of action arising out of or related to this +Agreement or the Software must be filed within one (1) year after such claim or +cause of action arose or be forever barred. + +12. ENTIRE AGREEMENT. This Agreement constitutes the entire agreement +between you and LMI regarding the subject matter of this Agreement, and +supersedes all prior communications, negotiations, understandings, agreements +or representations, either written or oral, if any. This Agreement may only be +amended in written form, executed by you and LMI. + +13. SEVERABILITY. If any provision of this Agreement is held for any +reason to be invalid or unenforceable, then the remaining provisions of this +Agreement will be unimpaired and, unless a modification or replacement of the +invalid or unenforceable provision is further held to deprive you or LMI of a +material benefit, in which case the Agreement will immediately terminate, the +invalid or unenforceable provision will be replaced with a provision that is +valid and enforceable and that comes closest to the intention underlying the +invalid or unenforceable provision. + +14. NO WAIVER. The waiver by LMI of any breach of any provision of this +Agreement will not operate or be construed as a waiver of any other or a +subsequent breach of the same or a different provision. diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/adc.c b/Demo/CORTEX_LM3S811_GCC/hw_include/adc.c new file mode 100644 index 000000000..53f3adf5b --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/adc.c @@ -0,0 +1,946 @@ +//***************************************************************************** +// +// adc.c - Driver for the ADC. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +//***************************************************************************** +// +//! \addtogroup adc_api +//! @{ +// +//***************************************************************************** + +#include "../hw_adc.h" +#include "../hw_ints.h" +#include "../hw_memmap.h" +#include "../hw_types.h" +#include "adc.h" +#include "debug.h" +#include "interrupt.h" + +//***************************************************************************** +// +// The currently configured software oversampling factor for each of the ADC +// sequencers. +// +//***************************************************************************** +#if defined(GROUP_pucoverssamplefactor) || defined(BUILD_ALL) +unsigned char g_pucOversampleFactor[3]; +#else +extern unsigned char g_pucOversampleFactor[3]; +#endif + +//***************************************************************************** +// +//! Registers an interrupt handler for an ADC interrupt. +//! +//! \param ulBase is the base address of the ADC module. +//! \param ulSequenceNum is the sample sequence number. +//! \param pfnHandler is a pointer to the function to be called when the +//! ADC sample sequence interrupt occurs. +//! +//! This function sets the handler to be called when a sample sequence +//! interrupt occurs. This will enable the global interrupt in the interrupt +//! controller; the sequence interrupt must be enabled with ADCIntEnable(). It +//! is the interrupt handler's responsibility to clear the interrupt source via +//! ADCIntClear(). +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intregister) || defined(BUILD_ALL) || defined(DOXYGEN) +void +ADCIntRegister(unsigned long ulBase, unsigned long ulSequenceNum, + void (*pfnHandler)(void)) +{ + unsigned long ulInt; + + // + // Check the arguments. + // + ASSERT(ulBase == ADC_BASE); + ASSERT(ulSequenceNum < 4); + + // + // Determine the interrupt to register based on the sequence number. + // + ulInt = INT_ADC0 + ulSequenceNum; + + // + // Register the interrupt handler. + // + IntRegister(ulInt, pfnHandler); + + // + // Enable the timer interrupt. + // + IntEnable(ulInt); +} +#endif + +//***************************************************************************** +// +//! Unregisters the interrupt handler for an ADC interrupt. +//! +//! \param ulBase is the base address of the ADC module. +//! \param ulSequenceNum is the sample sequence number. +//! +//! This function unregisters the interrupt handler. This will disable the +//! global interrupt in the interrupt controller; the sequence interrupt must +//! be disabled via ADCIntDisable(). +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intunregister) || defined(BUILD_ALL) || defined(DOXYGEN) +void +ADCIntUnregister(unsigned long ulBase, unsigned long ulSequenceNum) +{ + unsigned long ulInt; + + // + // Check the arguments. + // + ASSERT(ulBase == ADC_BASE); + ASSERT(ulSequenceNum < 4); + + // + // Determine the interrupt to unregister based on the sequence number. + // + ulInt = INT_ADC0 + ulSequenceNum; + + // + // Disable the interrupt. + // + IntDisable(ulInt); + + // + // Unregister the interrupt handler. + // + IntUnregister(ulInt); +} +#endif + +//***************************************************************************** +// +//! Disables a sample sequence interrupt. +//! +//! \param ulBase is the base address of the ADC module. +//! \param ulSequenceNum is the sample sequence number. +//! +//! This function disables the requested sample sequence interrupt. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intdisable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +ADCIntDisable(unsigned long ulBase, unsigned long ulSequenceNum) +{ + // + // Check the arguments. + // + ASSERT(ulBase == ADC_BASE); + ASSERT(ulSequenceNum < 4); + + // + // Disable this sample sequence interrupt. + // + HWREG(ulBase + ADC_O_IM) &= ~(1 << ulSequenceNum); +} +#endif + +//***************************************************************************** +// +//! Enables a sample sequence interrupt. +//! +//! \param ulBase is the base address of the ADC module. +//! \param ulSequenceNum is the sample sequence number. +//! +//! This function enables the requested sample sequence interrupt. Any +//! outstanding interrupts are cleared before enabling the sample sequence +//! interrupt. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intenable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +ADCIntEnable(unsigned long ulBase, unsigned long ulSequenceNum) +{ + // + // Check the arguments. + // + ASSERT(ulBase == ADC_BASE); + ASSERT(ulSequenceNum < 4); + + // + // Clear any outstanding interrupts on this sample sequence. + // + HWREG(ulBase + ADC_O_ISC) = 1 << ulSequenceNum; + + // + // Enable this sample sequence interrupt. + // + HWREG(ulBase + ADC_O_IM) |= 1 << ulSequenceNum; +} +#endif + +//***************************************************************************** +// +//! Gets the current interrupt status. +//! +//! \param ulBase is the base address of the ADC module. +//! \param ulSequenceNum is the sample sequence number. +//! \param bMasked is false if the raw interrupt status is required and true if +//! the masked interrupt status is required. +//! +//! This returns the interrupt status for the specified sample sequence. +//! Either the raw interrupt status or the status of interrupts that are +//! allowed to reflect to the processor can be returned. +//! +//! \return The current raw or masked interrupt status. +// +//***************************************************************************** +#if defined(GROUP_intstatus) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +ADCIntStatus(unsigned long ulBase, unsigned long ulSequenceNum, + tBoolean bMasked) +{ + // + // Check the arguments. + // + ASSERT(ulBase == ADC_BASE); + ASSERT(ulSequenceNum < 4); + + // + // Return either the interrupt status or the raw interrupt status as + // requested. + // + if(bMasked) + { + return(HWREG(ulBase + ADC_O_ISC) & (1 << ulSequenceNum)); + } + else + { + return(HWREG(ulBase + ADC_O_RIS) & (1 << ulSequenceNum)); + } +} +#endif + +//***************************************************************************** +// +//! Clears sample sequence interrupt source. +//! +//! \param ulBase is the base address of the ADC module. +//! \param ulSequenceNum is the sample sequence number. +//! +//! The specified sample sequence interrupt is cleared, so that it no longer +//! asserts. This must be done in the interrupt handler to keep it from being +//! called again immediately upon exit. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intclear) || defined(BUILD_ALL) || defined(DOXYGEN) +void +ADCIntClear(unsigned long ulBase, unsigned long ulSequenceNum) +{ + // + // Check the arugments. + // + ASSERT(ulBase == ADC_BASE); + ASSERT(ulSequenceNum < 4); + + // + // Clear the interrupt. + // + HWREG(ulBase + ADC_O_ISC) = 1 << ulSequenceNum; +} +#endif + +//***************************************************************************** +// +//! Enables a sample sequence. +//! +//! \param ulBase is the base address of the ADC module. +//! \param ulSequenceNum is the sample sequence number. +//! +//! Allows the specified sample sequence to be captured when its trigger is +//! detected. A sample sequence must be configured before it is enabled. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_sequenceenable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +ADCSequenceEnable(unsigned long ulBase, unsigned long ulSequenceNum) +{ + // + // Check the arugments. + // + ASSERT(ulBase == ADC_BASE); + ASSERT(ulSequenceNum < 4); + + // + // Enable the specified sequence. + // + HWREG(ulBase + ADC_O_ACTSS) |= 1 << ulSequenceNum; +} +#endif + +//***************************************************************************** +// +//! Disables a sample sequence. +//! +//! \param ulBase is the base address of the ADC module. +//! \param ulSequenceNum is the sample sequence number. +//! +//! Prevents the specified sample sequence from being captured when its trigger +//! is detected. A sample sequence should be disabled before it is configured. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_sequencedisable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +ADCSequenceDisable(unsigned long ulBase, unsigned long ulSequenceNum) +{ + // + // Check the arugments. + // + ASSERT(ulBase == ADC_BASE); + ASSERT(ulSequenceNum < 4); + + // + // Disable the specified sequences. + // + HWREG(ulBase + ADC_O_ACTSS) &= ~(1 << ulSequenceNum); +} +#endif + +//***************************************************************************** +// +//! Configures the trigger source and priority of a sample sequence. +//! +//! \param ulBase is the base address of the ADC module. +//! \param ulSequenceNum is the sample sequence number. +//! \param ulTrigger is the trigger source that initiates the sample sequence; +//! must be one of the \b ADC_TRIGGER_* values. +//! \param ulPriority is the relative priority of the sample sequence with +//! respect to the other sample sequences. +//! +//! This function configures the initiation criteria for a sample sequence. +//! Valid sample sequences range from zero to three; sequence zero will capture +//! up to eight samples, sequences one and two will capture up to four samples, +//! and sequence three will capture a single sample. The trigger condition and +//! priority (with respect to other sample sequence execution) is set. +//! +//! The parameter \b ulTrigger can take on the following values: +//! +//! - \b ADC_TRIGGER_PROCESSOR - A trigger generated by the processor, via the +//! ADCProcessorTrigger() function. +//! - \b ADC_TRIGGER_COMP0 - A trigger generated by the first analog +//! comparator; configured with ComparatorConfigure(). +//! - \b ADC_TRIGGER_COMP1 - A trigger generated by the second analog +//! comparator; configured with ComparatorConfigure(). +//! - \b ADC_TRIGGER_COMP2 - A trigger generated by the third analog +//! comparator; configured with ComparatorConfigure(). +//! - \b ADC_TRIGGER_EXTERNAL - A trigger generated by an input from the Port +//! B4 pin. +//! - \b ADC_TRIGGER_TIMER - A trigger generated by a timer; configured with +//! TimerControlTrigger(). +//! - \b ADC_TRIGGER_PWM0 - A trigger generated by the first PWM generator; +//! configured with PWMGenIntTrigEnable(). +//! - \b ADC_TRIGGER_PWM1 - A trigger generated by the second PWM generator; +//! configured with PWMGenIntTrigEnable(). +//! - \b ADC_TRIGGER_PWM2 - A trigger generated by the third PWM generator; +//! configured with PWMGenIntTrigEnable(). +//! - \b ADC_TRIGGER_ALWAYS - A trigger that is always asserted, causing the +//! sample sequence to capture repeatedly (so long as +//! there is not a higher priority source active). +//! +//! Note that not all trigger sources are available on all Stellaris family +//! members; consult the data sheet for the device in question to determine the +//! availability of triggers. +//! +//! The parameter \b ulPriority is a value between 0 and 3, where 0 represents +//! the highest priority and 3 the lowest. Note that when programming the +//! priority among a set of sample sequences, each must have unique priority; +//! it is up to the caller to guarantee the uniqueness of the priorities. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_sequenceconfigure) || defined(BUILD_ALL) || defined(DOXYGEN) +void +ADCSequenceConfigure(unsigned long ulBase, unsigned long ulSequenceNum, + unsigned long ulTrigger, unsigned long ulPriority) +{ + // + // Check the arugments. + // + ASSERT(ulBase == ADC_BASE); + ASSERT(ulSequenceNum < 4); + ASSERT((ulTrigger == ADC_TRIGGER_PROCESSOR) || + (ulTrigger == ADC_TRIGGER_COMP0) || + (ulTrigger == ADC_TRIGGER_COMP1) || + (ulTrigger == ADC_TRIGGER_COMP2) || + (ulTrigger == ADC_TRIGGER_EXTERNAL) || + (ulTrigger == ADC_TRIGGER_TIMER) || + (ulTrigger == ADC_TRIGGER_PWM0) || + (ulTrigger == ADC_TRIGGER_PWM1) || + (ulTrigger == ADC_TRIGGER_PWM2) || + (ulTrigger == ADC_TRIGGER_ALWAYS)); + ASSERT(ulPriority < 4); + + // + // Compute the shift for the bits that control this sample sequence. + // + ulSequenceNum *= 4; + + // + // Set the trigger event for this sample sequence. + // + HWREG(ulBase + ADC_O_EMUX) = ((HWREG(ulBase + ADC_O_EMUX) & + ~(0xf << ulSequenceNum)) | + ((ulTrigger & 0xf) << ulSequenceNum)); + + // + // Set the priority for this sample sequence. + // + HWREG(ulBase + ADC_O_SSPRI) = ((HWREG(ulBase + ADC_O_SSPRI) & + ~(0xf << ulSequenceNum)) | + ((ulPriority & 0x3) << ulSequenceNum)); +} +#endif + +//***************************************************************************** +// +//! Configure a step of the sample sequencer. +//! +//! \param ulBase is the base address of the ADC module. +//! \param ulSequenceNum is the sample sequence number. +//! \param ulStep is the step to be configured. +//! \param ulConfig is the configuration of this step; must be a logical OR of +//! \b ADC_CTL_TS, \b ADC_CTL_IE, \b ADC_CTL_END, \b ADC_CTL_D, and one of the +//! input channel selects (\b ADC_CTL_CH0 through \b ADC_CTL_CH7). +//! +//! This function will set the configuration of the ADC for one step of a +//! sample sequence. The ADC can be configured for single-ended or +//! differential operation (the \b ADC_CTL_D bit selects differential +//! operation when set), the channel to be sampled can be chosen (the +//! \b ADC_CTL_CH0 through \b ADC_CTL_CH7 values), and the internal temperature +//! sensor can be selected (the \b ADC_CTL_TS bit). Additionally, this step +//! can be defined as the last in the sequence (the \b ADC_CTL_END bit) and it +//! can be configured to cause an interrupt when the step is complete (the +//! \b ADC_CTL_IE bit). The configuration is used by the ADC at the +//! appropriate time when the trigger for this sequence occurs. +//! +//! The \b ulStep parameter determines the order in which the samples are +//! captured by the ADC when the trigger occurs. It can range from zero to +//! seven for the first sample sequence, from zero to three for the second and +//! third sample sequence, and can only be zero for the fourth sample sequence. +//! +//! Differential mode only works with adjacent channel pairs (e.g. 0 and 1). +//! The channel select must be the number of the channel pair to sample (e.g. +//! \b ADC_CTL_CH0 for 0 and 1, or \b ADC_CTL_CH1 for 2 and 3) or undefined +//! results will be returned by the ADC. Additionally, if differential mode is +//! selected when the temperature sensor is being sampled, undefined results +//! will be returned by the ADC. +//! +//! It is the responsibility of the caller to ensure that a valid configuration +//! is specified; this function does not check the validity of the specified +//! configuration. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_sequencestepconfigure) || defined(BUILD_ALL) || \ + defined(DOXYGEN) +void +ADCSequenceStepConfigure(unsigned long ulBase, unsigned long ulSequenceNum, + unsigned long ulStep, unsigned long ulConfig) +{ + // + // Check the arugments. + // + ASSERT(ulBase == ADC_BASE); + ASSERT(ulSequenceNum < 4); + ASSERT(((ulSequenceNum == 0) && (ulStep < 8)) || + ((ulSequenceNum == 1) && (ulStep < 4)) || + ((ulSequenceNum == 2) && (ulStep < 4)) || + ((ulSequenceNum == 3) && (ulStep < 1))); + + // + // Get the offset of the sequence to be configured. + // + ulBase += ADC_O_SEQ + (ADC_O_SEQ_STEP * ulSequenceNum); + + // + // Compute the shift for the bits that control this step. + // + ulStep *= 4; + + // + // Set the analog mux value for this step. + // + HWREG(ulBase + ADC_O_X_SSMUX) = ((HWREG(ulBase + ADC_O_X_SSMUX) & + ~(0x0000000f << ulStep)) | + ((ulConfig & 0x0f) << ulStep)); + + // + // Set the control value for this step. + // + HWREG(ulBase + ADC_O_X_SSCTL) = ((HWREG(ulBase + ADC_O_X_SSCTL) & + ~(0x0000000f << ulStep)) | + (((ulConfig & 0xf0) >> 4) << ulStep)); +} +#endif + +//***************************************************************************** +// +//! Determines if a sample sequence overflow occurred. +//! +//! \param ulBase is the base address of the ADC module. +//! \param ulSequenceNum is the sample sequence number. +//! +//! This determines if a sample sequence overflow has occurred. This will +//! happen if the captured samples are not read from the FIFO before the next +//! trigger occurs. +//! +//! \return Returns zero if there was not an overflow, and non-zero if there +//! was. +// +//***************************************************************************** +#if defined(GROUP_sequenceoverflow) || defined(BUILD_ALL) || defined(DOXYGEN) +long +ADCSequenceOverflow(unsigned long ulBase, unsigned long ulSequenceNum) +{ + // + // Check the arguments. + // + ASSERT(ulBase == ADC_BASE); + ASSERT(ulSequenceNum < 4); + + // + // Determine if there was an overflow on this sequence. + // + return(HWREG(ulBase + ADC_O_OSTAT) & (1 << ulSequenceNum)); +} +#endif + +//***************************************************************************** +// +//! Determines if a sample sequence underflow occurred. +//! +//! \param ulBase is the base address of the ADC module. +//! \param ulSequenceNum is the sample sequence number. +//! +//! This determines if a sample sequence underflow has occurred. This will +//! happen if too many samples are read from the FIFO. +//! +//! \return Returns zero if there was not an underflow, and non-zero if there +//! was. +// +//***************************************************************************** +#if defined(GROUP_sequenceunderflow) || defined(BUILD_ALL) || defined(DOXYGEN) +long +ADCSequenceUnderflow(unsigned long ulBase, unsigned long ulSequenceNum) +{ + // + // Check the arguments. + // + ASSERT(ulBase == ADC_BASE); + ASSERT(ulSequenceNum < 4); + + // + // Determine if there was an underflow on this sequence. + // + return(HWREG(ulBase + ADC_O_USTAT) & (1 << ulSequenceNum)); +} +#endif + +//***************************************************************************** +// +//! Gets the captured data for a sample sequence. +//! +//! \param ulBase is the base address of the ADC module. +//! \param ulSequenceNum is the sample sequence number. +//! \param pulBuffer is the address where the data is stored. +//! +//! This function copies data from the specified sample sequence output FIFO to +//! a memory resident buffer. The number of samples available in the hardware +//! FIFO are copied into the buffer, which is assumed to be large enough to +//! hold that many samples. This will only return the samples that are +//! presently available, which may not be the entire sample sequence if it is +//! in the process of being executed. +//! +//! \return Returns the number of samples copied to the buffer. +// +//***************************************************************************** +#if defined(GROUP_sequencedataget) || defined(BUILD_ALL) || defined(DOXYGEN) +long +ADCSequenceDataGet(unsigned long ulBase, unsigned long ulSequenceNum, + unsigned long *pulBuffer) +{ + unsigned long ulCount; + + // + // Check the arguments. + // + ASSERT(ulBase == ADC_BASE); + ASSERT(ulSequenceNum < 4); + + // + // Get the offset of the sequence to be read. + // + ulBase += ADC_O_SEQ + (ADC_O_SEQ_STEP * ulSequenceNum); + + // + // Read samples from the FIFO until it is empty. + // + ulCount = 0; + while(!(HWREG(ulBase + ADC_O_X_SSFSTAT) & ADC_SSFSTAT_EMPTY) && + (ulCount < 8)) + { + // + // Read the FIFO and copy it to the destination. + // + *pulBuffer++ = HWREG(ulBase + ADC_O_X_SSFIFO); + + // + // Increment the count of samples read. + // + ulCount++; + } + + // + // Return the number of samples read. + // + return(ulCount); +} +#endif + +//***************************************************************************** +// +//! Causes a processor trigger for a sample sequence. +//! +//! \param ulBase is the base address of the ADC module. +//! \param ulSequenceNum is the sample sequence number. +//! +//! This function triggers a processor-initiated sample sequence if the sample +//! sequence trigger is configured to ADC_TRIGGER_PROCESSOR. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_processortrigger) || defined(BUILD_ALL) || defined(DOXYGEN) +void +ADCProcessorTrigger(unsigned long ulBase, unsigned long ulSequenceNum) +{ + // + // Check the arguments. + // + ASSERT(ulBase == ADC_BASE); + ASSERT(ulSequenceNum < 4); + + // + // Generate a processor trigger for this sample sequence. + // + HWREG(ulBase + ADC_O_PSSI) = 1 << ulSequenceNum; +} +#endif + +//***************************************************************************** +// +//! Configures the software oversampling factor of the ADC. +//! +//! \param ulBase is the base address of the ADC module. +//! \param ulSequenceNum is the sample sequence number. +//! \param ulFactor is the number of samples to be averaged. +//! +//! This function configures the software oversampling for the ADC, which can +//! be used to provide better resolution on the sampled data. Oversampling is +//! accomplished by averaging multiple samples from the same analog input. +//! Three different oversampling rates are supported; 2x, 4x, and 8x. +//! +//! Oversampling is only supported on the sample sequencers that are more than +//! one sample in depth (i.e. the fourth sample sequencer is not supported). +//! Oversampling by 2x (for example) divides the depth of the sample sequencer +//! by two; so 2x oversampling on the first sample sequencer can only provide +//! four samples per trigger. This also means that 8x oversampling is only +//! available on the first sample sequencer. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_softwareoversampleconfigure) || defined(BUILD_ALL) || \ + defined(DOXYGEN) +void +ADCSoftwareOversampleConfigure(unsigned long ulBase, + unsigned long ulSequenceNum, + unsigned long ulFactor) +{ + unsigned long ulValue; + + // + // Check the arguments. + // + ASSERT(ulBase == ADC_BASE); + ASSERT(ulSequenceNum < 3); + ASSERT(((ulFactor == 2) || (ulFactor == 4) || (ulFactor == 8)) && + ((ulSequenceNum == 0) || (ulFactor != 8))); + + // + // Convert the oversampling factor to a shift factor. + // + for(ulValue = 0, ulFactor >>= 1; ulFactor; ulValue++, ulFactor >>= 1) + { + } + + // + // Save the sfiht factor. + // + g_pucOversampleFactor[ulSequenceNum] = ulValue; +} +#endif + +//***************************************************************************** +// +//! Configures a step of the software oversampled sequencer. +//! +//! \param ulBase is the base address of the ADC module. +//! \param ulSequenceNum is the sample sequence number. +//! \param ulStep is the step to be configured. +//! \param ulConfig is the configuration of this step. +//! +//! This function configures a step of the sample sequencer when using the +//! software oversampling feature. The number of steps available depends on +//! the oversampling factor set by ADCSoftwareOversampleConfigure(). The value +//! of \e ulConfig is the same as defined for ADCSequenceStepConfigure(). +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_softwareoversamplestepconfigure) || defined(BUILD_ALL) || \ + defined(DOXYGEN) +void +ADCSoftwareOversampleStepConfigure(unsigned long ulBase, + unsigned long ulSequenceNum, + unsigned long ulStep, + unsigned long ulConfig) +{ + // + // Check the arguments. + // + ASSERT(ulBase == ADC_BASE); + ASSERT(ulSequenceNum < 3); + ASSERT(((ulSequenceNum == 0) && + (ulStep < (8 >> g_pucOversampleFactor[ulSequenceNum]))) || + (ulStep < (4 >> g_pucOversampleFactor[ulSequenceNum]))); + + // + // Get the offset of the sequence to be configured. + // + ulBase += ADC_O_SEQ + (ADC_O_SEQ_STEP * ulSequenceNum); + + // + // Compute the shift for the bits that control this step. + // + ulStep *= 4 << g_pucOversampleFactor[ulSequenceNum]; + + // + // Loop through the hardware steps that make up this step of the software + // oversampled sequence. + // + for(ulSequenceNum = 1 << g_pucOversampleFactor[ulSequenceNum]; + ulSequenceNum; ulSequenceNum--) + { + // + // Set the analog mux value for this step. + // + HWREG(ulBase + ADC_O_X_SSMUX) = ((HWREG(ulBase + ADC_O_X_SSMUX) & + ~(0x0000000f << ulStep)) | + ((ulConfig & 0x0f) << ulStep)); + + // + // Set the control value for this step. + // + HWREG(ulBase + ADC_O_X_SSCTL) = ((HWREG(ulBase + ADC_O_X_SSCTL) & + ~(0x0000000f << ulStep)) | + (((ulConfig & 0xf0) >> 4) << ulStep)); + if(ulSequenceNum != 1) + { + HWREG(ulBase + ADC_O_X_SSCTL) &= ~((ADC_SSCTL_IE0 | + ADC_SSCTL_END0) << ulStep); + } + + // + // Go to the next hardware step. + // + ulStep += 4; + } +} +#endif + +//***************************************************************************** +// +//! Gets the captured data for a sample sequence using software oversampling. +//! +//! \param ulBase is the base address of the ADC module. +//! \param ulSequenceNum is the sample sequence number. +//! \param pulBuffer is the address where the data is stored. +//! \param ulCount is the number of samples to be read. +//! +//! This function copies data from the specified sample sequence output FIFO to +//! a memory resident buffer with software oversampling applied. The requested +//! number of samples are copied into the data buffer; if there are not enough +//! samples in the hardware FIFO to satisfy this many oversampled data items +//! then incorrect results will be returned. It is the caller's responsibility +//! to read only the samples that are available and wait until enough data is +//! available, for example as a result of receiving an interrupt. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_softwareoversampledataget) || defined(BUILD_ALL) || \ + defined(DOXYGEN) +void +ADCSoftwareOversampleDataGet(unsigned long ulBase, unsigned long ulSequenceNum, + unsigned long *pulBuffer, unsigned long ulCount) +{ + unsigned long ulIdx, ulAccum; + + // + // Check the arguments. + // + ASSERT(ulBase == ADC_BASE); + ASSERT(ulSequenceNum < 3); + ASSERT(((ulSequenceNum == 0) && + (ulCount < (8 >> g_pucOversampleFactor[ulSequenceNum]))) || + (ulCount < (4 >> g_pucOversampleFactor[ulSequenceNum]))); + + // + // Get the offset of the sequence to be read. + // + ulBase += ADC_O_SEQ + (ADC_O_SEQ_STEP * ulSequenceNum); + + // + // Read the samples from the FIFO until it is empty. + // + while(ulCount--) + { + // + // Compute the sum of the samples. + // + ulAccum = 0; + for(ulIdx = 1 << g_pucOversampleFactor[ulSequenceNum]; ulIdx; ulIdx--) + { + // + // Read the FIFO and add it to the accumulator. + // + ulAccum += HWREG(ulBase + ADC_O_X_SSFIFO); + } + + // + // Write the averaged sample to the output buffer. + // + *pulBuffer++ = ulAccum >> g_pucOversampleFactor[ulSequenceNum]; + } +} +#endif + +//***************************************************************************** +// +//! Configures the hardware oversampling factor of the ADC. +//! +//! \param ulBase is the base address of the ADC module. +//! \param ulFactor is the number of samples to be averaged. +//! +//! This function configures the hardware oversampling for the ADC, which can +//! be used to provide better resolution on the sampled data. Oversampling is +//! accomplished by averaging multiple samples from the same analog input. Six +//! different oversampling rates are supported; 2x, 4x, 8x, 16x, 32x, and 64x. +//! Specifying an oversampling factor of zero will disable the hardware +//! oversampler. +//! +//! Hardware oversampling applies uniformly to all sample sequencers. It does +//! not reduce the depth of the sample sequencers like the software +//! oversampling APIs; each sample written into the sample sequence FIFO is a +//! fully oversampled analog input reading. +//! +//! Enabling hardware averaging increases the precision of the ADC at the cost +//! of throughput. For example, enabling 4x oversampling reduces the +//! throughput of a 250 KSps ADC to 62.5 KSps. +//! +//! \note Hardware oversampling is available beginning with Rev C0 of the +//! Stellaris microcontroller. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_hardwareoversampleconfigure) || defined(BUILD_ALL) || \ + defined(DOXYGEN) +void +ADCHardwareOversampleConfigure(unsigned long ulBase, + unsigned long ulFactor) +{ + unsigned long ulValue; + + // + // Check the arguments. + // + ASSERT(ulBase == ADC_BASE); + ASSERT(((ulFactor == 0) || (ulFactor == 2) || (ulFactor == 4) || + (ulFactor == 8) || (ulFactor == 16) || (ulFactor == 32) || + (ulFactor == 64))); + + // + // Convert the oversampling factor to a shift factor. + // + for(ulValue = 0, ulFactor >>= 1; ulFactor; ulValue++, ulFactor >>= 1) + { + } + + // + // Write the shift factor to the ADC to configure the hardware oversampler. + // + HWREG(ulBase + ADC_O_SAC) = ulValue; +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/adc.h b/Demo/CORTEX_LM3S811_GCC/hw_include/adc.h new file mode 100644 index 000000000..c1fa37da4 --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/adc.h @@ -0,0 +1,126 @@ +//***************************************************************************** +// +// adc.h - ADC headers for using the ADC driver functions. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +#ifndef __ADC_H__ +#define __ADC_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// Values that can be passed to ADCSequenceConfigure as the ulTrigger +// parameter. +// +//***************************************************************************** +#define ADC_TRIGGER_PROCESSOR 0x00000000 // Processor event +#define ADC_TRIGGER_COMP0 0x00000001 // Analog comparator 0 event +#define ADC_TRIGGER_COMP1 0x00000002 // Analog comparator 1 event +#define ADC_TRIGGER_COMP2 0x00000003 // Analog comparator 2 event +#define ADC_TRIGGER_EXTERNAL 0x00000004 // External event +#define ADC_TRIGGER_TIMER 0x00000005 // Timer event +#define ADC_TRIGGER_PWM0 0x00000006 // PWM0 event +#define ADC_TRIGGER_PWM1 0x00000007 // PWM1 event +#define ADC_TRIGGER_PWM2 0x00000008 // PWM2 event +#define ADC_TRIGGER_ALWAYS 0x0000000F // Always event + +//***************************************************************************** +// +// Values that can be passed to ADCSequenceStepConfigure as the ulConfig +// parameter. +// +//***************************************************************************** +#define ADC_CTL_TS 0x00000080 // Temperature sensor select +#define ADC_CTL_IE 0x00000040 // Interrupt enable +#define ADC_CTL_END 0x00000020 // Sequence end select +#define ADC_CTL_D 0x00000010 // Differential select +#define ADC_CTL_CH0 0x00000000 // Input channel 0 +#define ADC_CTL_CH1 0x00000001 // Input channel 1 +#define ADC_CTL_CH2 0x00000002 // Input channel 2 +#define ADC_CTL_CH3 0x00000003 // Input channel 3 +#define ADC_CTL_CH4 0x00000004 // Input channel 4 +#define ADC_CTL_CH5 0x00000005 // Input channel 5 +#define ADC_CTL_CH6 0x00000006 // Input channel 6 +#define ADC_CTL_CH7 0x00000007 // Input channel 7 + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** +extern void ADCIntRegister(unsigned long ulBase, unsigned long ulSequenceNum, + void (*pfnHandler)(void)); +extern void ADCIntUnregister(unsigned long ulBase, + unsigned long ulSequenceNum); +extern void ADCIntDisable(unsigned long ulBase, unsigned long ulSequenceNum); +extern void ADCIntEnable(unsigned long ulBase, unsigned long ulSequenceNum); +extern unsigned long ADCIntStatus(unsigned long ulBase, + unsigned long ulSequenceNum, + tBoolean bMasked); +extern void ADCIntClear(unsigned long ulBase, unsigned long ulSequenceNum); +extern void ADCSequenceEnable(unsigned long ulBase, + unsigned long ulSequenceNum); +extern void ADCSequenceDisable(unsigned long ulBase, + unsigned long ulSequenceNum); +extern void ADCSequenceConfigure(unsigned long ulBase, + unsigned long ulSequenceNum, + unsigned long ulTrigger, + unsigned long ulPriority); +extern void ADCSequenceStepConfigure(unsigned long ulBase, + unsigned long ulSequenceNum, + unsigned long ulStep, + unsigned long ulConfig); +extern long ADCSequenceOverflow(unsigned long ulBase, + unsigned long ulSequenceNum); +extern long ADCSequenceUnderflow(unsigned long ulBase, + unsigned long ulSequenceNum); +extern long ADCSequenceDataGet(unsigned long ulBase, + unsigned long ulSequenceNum, + unsigned long *pulBuffer); +extern void ADCProcessorTrigger(unsigned long ulBase, + unsigned long ulSequenceNum); +extern void ADCSoftwareOversampleConfigure(unsigned long ulBase, + unsigned long ulSequenceNum, + unsigned long ulFactor); +extern void ADCSoftwareOversampleStepConfigure(unsigned long ulBase, + unsigned long ulSequenceNum, + unsigned long ulStep, + unsigned long ulConfig); +extern void ADCSoftwareOversampleDataGet(unsigned long ulBase, + unsigned long ulSequenceNum, + unsigned long *pulBuffer, + unsigned long ulCount); +extern void ADCHardwareOversampleConfigure(unsigned long ulBase, + unsigned long ulFactor); + +#ifdef __cplusplus +} +#endif + +#endif // __ADC_H__ diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/comp.c b/Demo/CORTEX_LM3S811_GCC/hw_include/comp.c new file mode 100644 index 000000000..aed156ea5 --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/comp.c @@ -0,0 +1,448 @@ +//***************************************************************************** +// +// comp.c - Driver for the analog comparator. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +//***************************************************************************** +// +//! \addtogroup comp_api +//! @{ +// +//***************************************************************************** + +#include "../hw_comp.h" +#include "../hw_ints.h" +#include "../hw_memmap.h" +#include "../hw_types.h" +#include "comp.h" +#include "debug.h" +#include "interrupt.h" + +//***************************************************************************** +// +//! Configures a comparator. +//! +//! \param ulBase is the base address of the comparator module. +//! \param ulComp is the index of the comparator to configure. +//! \param ulConfig is the configuration of the comparator. +//! +//! This function will configure a comparator. The \e ulConfig parameter is +//! the result of a logical OR operation between the \b COMP_TRIG_xxx, +//! \b COMP_INT_xxx, \b COMP_ASRCP_xxx, and \b COMP_OUTPUT_xxx values. +//! +//! The \b COMP_TRIG_xxx term can take on the following values: +//! +//! - \b COMP_TRIG_NONE to have no trigger to the ADC. +//! - \b COMP_TRIG_HIGH to trigger the ADC when the comparator output is high. +//! - \b COMP_TRIG_LOW to trigger the ADC when the comparator output is low. +//! - \b COMP_TRIG_FALL to trigger the ADC when the comparator output goes low. +//! - \b COMP_TRIG_RISE to trigger the ADC when the comparator output goes +//! high. +//! - \b COMP_TRIG_BOTH to trigger the ADC when the comparator output goes low +//! or high. +//! +//! The \b COMP_INT_xxx term can take on the following values: +//! +//! - \b COMP_INT_HIGH to generate an interrupt when the comparator output is +//! high. +//! - \b COMP_INT_LOW to generate an interrupt when the comparator output is +//! low. +//! - \b COMP_INT_FALL to generate an interrupt when the comparator output goes +//! low. +//! - \b COMP_INT_RISE to generate an interrupt when the comparator output goes +//! high. +//! - \b COMP_INT_BOTH to generate an interrupt when the comparator output goes +//! low or high. +//! +//! The \b COMP_ASRCP_xxx term can take on the following values: +//! +//! - \b COMP_ASRCP_PIN to use the dedicated Comp+ pin as the reference +//! voltage. +//! - \b COMP_ASRCP_PIN0 to use the Comp0+ pin as the reference voltage (this +//! the same as \b COMP_ASRCP_PIN for the comparator 0). +//! - \b COMP_ASRCP_REF to use the internally generated voltage as the +//! reference voltage. +//! +//! The \b COMP_OUTPUT_xxx term can take on the following values: +//! +//! - \b COMP_OUTPUT_NONE to disable the output from the comparator to a device +//! pin. +//! - \b COMP_OUTPUT_NORMAL to enable a non-inverted output from the comparator +//! to a device pin. +//! - \b COMP_OUTPUT_INVERT to enable an inverted output from the comparator to +//! a device pin. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_configure) || defined(BUILD_ALL) || defined(DOXYGEN) +void +ComparatorConfigure(unsigned long ulBase, unsigned long ulComp, + unsigned long ulConfig) +{ + // + // Check the arguments. + // + ASSERT(ulBase == COMP_BASE); + ASSERT(ulComp < 3); + + // + // Configure this comparator. + // + HWREG(ulBase + (ulComp * 0x20) + COMP_O_ACCTL0) = ulConfig; +} +#endif + +//***************************************************************************** +// +//! Sets the internal reference voltage. +//! +//! \param ulBase is the base address of the comparator module. +//! \param ulRef is the desired reference voltage. +//! +//! This function will set the internal reference voltage value. The voltage +//! is specified as one of the following values: +//! +//! - \b COMP_REF_OFF to turn off the reference voltage +//! - \b COMP_REF_0V to set the reference voltage to 0 V +//! - \b COMP_REF_0_1375V to set the reference voltage to 0.1375 V +//! - \b COMP_REF_0_275V to set the reference voltage to 0.275 V +//! - \b COMP_REF_0_4125V to set the reference voltage to 0.4125 V +//! - \b COMP_REF_0_55V to set the reference voltage to 0.55 V +//! - \b COMP_REF_0_6875V to set the reference voltage to 0.6875 V +//! - \b COMP_REF_0_825V to set the reference voltage to 0.825 V +//! - \b COMP_REF_0_928125V to set the reference voltage to 0.928125 V +//! - \b COMP_REF_0_9625V to set the reference voltage to 0.9625 V +//! - \b COMP_REF_1_03125V to set the reference voltage to 1.03125 V +//! - \b COMP_REF_1_134375V to set the reference voltage to 1.134375 V +//! - \b COMP_REF_1_1V to set the reference voltage to 1.1 V +//! - \b COMP_REF_1_2375V to set the reference voltage to 1.2375 V +//! - \b COMP_REF_1_340625V to set the reference voltage to 1.340625 V +//! - \b COMP_REF_1_375V to set the reference voltage to 1.375 V +//! - \b COMP_REF_1_44375V to set the reference voltage to 1.44375 V +//! - \b COMP_REF_1_5125V to set the reference voltage to 1.5125 V +//! - \b COMP_REF_1_546875V to set the reference voltage to 1.546875 V +//! - \b COMP_REF_1_65V to set the reference voltage to 1.65 V +//! - \b COMP_REF_1_753125V to set the reference voltage to 1.753125 V +//! - \b COMP_REF_1_7875V to set the reference voltage to 1.7875 V +//! - \b COMP_REF_1_85625V to set the reference voltage to 1.85625 V +//! - \b COMP_REF_1_925V to set the reference voltage to 1.925 V +//! - \b COMP_REF_1_959375V to set the reference voltage to 1.959375 V +//! - \b COMP_REF_2_0625V to set the reference voltage to 2.0625 V +//! - \b COMP_REF_2_165625V to set the reference voltage to 2.165625 V +//! - \b COMP_REF_2_26875V to set the reference voltage to 2.26875 V +//! - \b COMP_REF_2_371875V to set the reference voltage to 2.371875 V +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_refset) || defined(BUILD_ALL) || defined(DOXYGEN) +void +ComparatorRefSet(unsigned long ulBase, unsigned long ulRef) +{ + // + // Check the arguments. + // + ASSERT(ulBase == COMP_BASE); + + // + // Set the voltage reference voltage as requested. + // + HWREG(ulBase + COMP_O_REFCTL) = ulRef; +} +#endif + +//***************************************************************************** +// +//! Gets the current comparator output value. +//! +//! \param ulBase is the base address of the comparator module. +//! \param ulComp is the index of the comparator. +//! +//! This function retrieves the current value of the comparator output. +//! +//! \return Returns \b true if the comparator output is high and \b false if +//! the comparator output is low. +// +//***************************************************************************** +#if defined(GROUP_valueget) || defined(BUILD_ALL) || defined(DOXYGEN) +tBoolean +ComparatorValueGet(unsigned long ulBase, unsigned long ulComp) +{ + // + // Check the arguments. + // + ASSERT(ulBase == COMP_BASE); + ASSERT(ulComp < 3); + + // + // Return the appropriate value based on the comparator's present output + // value. + // + if(HWREG(ulBase + (ulComp * 0x20) + COMP_O_ACSTAT0) & COMP_ACSTAT_OVAL) + { + return(true); + } + else + { + return(false); + } +} +#endif + +//***************************************************************************** +// +//! Registers an interrupt handler for the comparator interrupt. +//! +//! \param ulBase is the base address of the comparator module. +//! \param ulComp is the index of the comparator. +//! \param pfnHandler is a pointer to the function to be called when the +//! comparator interrupt occurs. +//! +//! This sets the handler to be called when the comparator interrupt occurs. +//! This will enable the interrupt in the interrupt controller; it is the +//! interrupt-handler's responsibility to clear the interrupt source via +//! ComparatorIntClear(). +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intregister) || defined(BUILD_ALL) || defined(DOXYGEN) +void +ComparatorIntRegister(unsigned long ulBase, unsigned long ulComp, + void (*pfnHandler)(void)) +{ + // + // Check the arguments. + // + ASSERT(ulBase == COMP_BASE); + ASSERT(ulComp < 3); + + // + // Register the interrupt handler, returning an error if an error occurs. + // + IntRegister(INT_COMP0 + ulComp, pfnHandler); + + // + // Enable the interrupt in the interrupt controller. + // + IntEnable(INT_COMP0 + ulComp); + + // + // Enable the comparator interrupt. + // + HWREG(ulBase + COMP_O_INTEN) |= 1 << ulComp; +} +#endif + +//***************************************************************************** +// +//! Unregisters an interrupt handler for a comparator interrupt. +//! +//! \param ulBase is the base address of the comparator module. +//! \param ulComp is the index of the comparator. +//! +//! This function will clear the handler to be called when a comparator +//! interrupt occurs. This will also mask off the interrupt in the interrupt +//! controller so that the interrupt handler no longer is called. +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intunregister) || defined(BUILD_ALL) || defined(DOXYGEN) +void +ComparatorIntUnregister(unsigned long ulBase, unsigned long ulComp) +{ + // + // Check the arguments. + // + ASSERT(ulBase == COMP_BASE); + ASSERT(ulComp < 3); + + // + // Disable the comparator interrupt. + // + HWREG(ulBase + COMP_O_INTEN) &= ~(1 << ulComp); + + // + // Disable the interrupt in the interrupt controller. + // + IntDisable(INT_COMP0 + ulComp); + + // + // Unregister the interrupt handler. + // + IntUnregister(INT_COMP0 + ulComp); +} +#endif + +//***************************************************************************** +// +//! Enables the comparator interrupt. +//! +//! \param ulBase is the base address of the comparator module. +//! \param ulComp is the index of the comparator. +//! +//! This function enables generation of an interrupt from the specified +//! comparator. Only comparators whose interrupts are enabled can be reflected +//! to the processor. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intenable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +ComparatorIntEnable(unsigned long ulBase, unsigned long ulComp) +{ + // + // Check the arguments. + // + ASSERT(ulBase == COMP_BASE); + ASSERT(ulComp < 3); + + // + // Enable the comparator interrupt. + // + HWREG(ulBase + COMP_O_INTEN) |= 1 << ulComp; +} +#endif + +//***************************************************************************** +// +//! Disables the comparator interrupt. +//! +//! \param ulBase is the base address of the comparator module. +//! \param ulComp is the index of the comparator. +//! +//! This function disables generation of an interrupt from the specified +//! comparator. Only comparators whose interrupts are enabled can be reflected +//! to the processor. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intdisable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +ComparatorIntDisable(unsigned long ulBase, unsigned long ulComp) +{ + // + // Check the arguments. + // + ASSERT(ulBase == COMP_BASE); + ASSERT(ulComp < 3); + + // + // Disable the comparator interrupt. + // + HWREG(ulBase + COMP_O_INTEN) &= ~(1 << ulComp); +} +#endif + +//***************************************************************************** +// +//! Gets the current interrupt status. +//! +//! \param ulBase is the base address of the comparator module. +//! \param ulComp is the index of the comparator. +//! \param bMasked is \b false if the raw interrupt status is required and +//! \b true if the masked interrupt status is required. +//! +//! This returns the interrupt status for the comparator. Either the raw or +//! the masked interrupt status can be returned. +//! +//! \return \b true if the interrupt is asserted and \b false if it is not +//! asserted. +// +//***************************************************************************** +#if defined(GROUP_intstatus) || defined(BUILD_ALL) || defined(DOXYGEN) +tBoolean +ComparatorIntStatus(unsigned long ulBase, unsigned long ulComp, + tBoolean bMasked) +{ + // + // Check the arguments. + // + ASSERT(ulBase == COMP_BASE); + ASSERT(ulComp < 3); + + // + // Return either the interrupt status or the raw interrupt status as + // requested. + // + if(bMasked) + { + return(((HWREG(ulBase + COMP_O_MIS) >> ulComp) & 1) ? true : false); + } + else + { + return(((HWREG(ulBase + COMP_O_RIS) >> ulComp) & 1) ? true : false); + } +} +#endif + +//***************************************************************************** +// +//! Clears a comparator interrupt. +//! +//! \param ulBase is the base address of the comparator module. +//! \param ulComp is the index of the comparator. +//! +//! The comparator interrupt is cleared, so that it no longer asserts. This +//! must be done in the interrupt handler to keep it from being called again +//! immediately upon exit. Note that for a level triggered interrupt, the +//! interrupt cannot be cleared until it stops asserting. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intclear) || defined(BUILD_ALL) || defined(DOXYGEN) +void +ComparatorIntClear(unsigned long ulBase, unsigned long ulComp) +{ + // + // Check the arguments. + // + ASSERT(ulBase == COMP_BASE); + ASSERT(ulComp < 3); + + // + // Clear the interrupt. + // + HWREG(ulBase + COMP_O_MIS) = 1 << ulComp; +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/comp.h b/Demo/CORTEX_LM3S811_GCC/hw_include/comp.h new file mode 100644 index 000000000..9349982c4 --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/comp.h @@ -0,0 +1,120 @@ +//***************************************************************************** +// +// comp.h - Prototypes for the analog comparator driver. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +#ifndef __COMP_H__ +#define __COMP_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// Values that can be passed to ComparatorConfigure() as the ulConfig +// parameter. For each group (i.e. COMP_TRIG_xxx, COMP_INT_xxx, etc.), one of +// the values may be selected and ORed together will values from the other +// groups. +// +//***************************************************************************** +#define COMP_TRIG_NONE 0x00000000 // No ADC trigger +#define COMP_TRIG_HIGH 0x00000880 // Trigger when high +#define COMP_TRIG_LOW 0x00000800 // Trigger when low +#define COMP_TRIG_FALL 0x00000820 // Trigger on falling edge +#define COMP_TRIG_RISE 0x00000840 // Trigger on rising edge +#define COMP_TRIG_BOTH 0x00000860 // Trigger on both edges +#define COMP_INT_HIGH 0x00000010 // Interrupt when high +#define COMP_INT_LOW 0x00000000 // Interrupt when low +#define COMP_INT_FALL 0x00000004 // Interrupt on falling edge +#define COMP_INT_RISE 0x00000008 // Interrupt on rising edge +#define COMP_INT_BOTH 0x0000000C // Interrupt on both edges +#define COMP_ASRCP_PIN 0x00000000 // Dedicated Comp+ pin +#define COMP_ASRCP_PIN0 0x00000200 // Comp0+ pin +#define COMP_ASRCP_REF 0x00000400 // Internal voltage reference +#define COMP_OUTPUT_NONE 0x00000000 // No comparator output +#define COMP_OUTPUT_NORMAL 0x00000100 // Comparator output normal +#define COMP_OUTPUT_INVERT 0x00000102 // Comparator output inverted + +//***************************************************************************** +// +// Values that can be passed to ComparatorSetRef() as the ulRef parameter. +// +//***************************************************************************** +#define COMP_REF_OFF 0x00000000 // Turn off the internal reference +#define COMP_REF_0V 0x00000300 // Internal reference of 0V +#define COMP_REF_0_1375V 0x00000301 // Internal reference of 0.1375V +#define COMP_REF_0_275V 0x00000302 // Internal reference of 0.275V +#define COMP_REF_0_4125V 0x00000303 // Internal reference of 0.4125V +#define COMP_REF_0_55V 0x00000304 // Internal reference of 0.55V +#define COMP_REF_0_6875V 0x00000305 // Internal reference of 0.6875V +#define COMP_REF_0_825V 0x00000306 // Internal reference of 0.825V +#define COMP_REF_0_928125V 0x00000201 // Internal reference of 0.928125V +#define COMP_REF_0_9625V 0x00000307 // Internal reference of 0.9625V +#define COMP_REF_1_03125V 0x00000202 // Internal reference of 1.03125V +#define COMP_REF_1_134375V 0x00000203 // Internal reference of 1.134375V +#define COMP_REF_1_1V 0x00000308 // Internal reference of 1.1V +#define COMP_REF_1_2375V 0x00000309 // Internal reference of 1.2375V +#define COMP_REF_1_340625V 0x00000205 // Internal reference of 1.340625V +#define COMP_REF_1_375V 0x0000030A // Internal reference of 1.375V +#define COMP_REF_1_44375V 0x00000206 // Internal reference of 1.44375V +#define COMP_REF_1_5125V 0x0000030B // Internal reference of 1.5125V +#define COMP_REF_1_546875V 0x00000207 // Internal reference of 1.546875V +#define COMP_REF_1_65V 0x0000030C // Internal reference of 1.65V +#define COMP_REF_1_753125V 0x00000209 // Internal reference of 1.753125V +#define COMP_REF_1_7875V 0x0000030D // Internal reference of 1.7875V +#define COMP_REF_1_85625V 0x0000020A // Internal reference of 1.85625V +#define COMP_REF_1_925V 0x0000030E // Internal reference of 1.925V +#define COMP_REF_1_959375V 0x0000020B // Internal reference of 1.959375V +#define COMP_REF_2_0625V 0x0000030F // Internal reference of 2.0625V +#define COMP_REF_2_165625V 0x0000020D // Internal reference of 2.165625V +#define COMP_REF_2_26875V 0x0000020E // Internal reference of 2.26875V +#define COMP_REF_2_371875V 0x0000020F // Internal reference of 2.371875V + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** +extern void ComparatorConfigure(unsigned long ulBase, unsigned long ulComp, + unsigned long ulConfig); +extern void ComparatorRefSet(unsigned long ulBase, unsigned long ulRef); +extern tBoolean ComparatorValueGet(unsigned long ulBase, unsigned long ulComp); +extern void ComparatorIntRegister(unsigned long ulBase, unsigned long ulComp, + void (*pfnHandler)(void)); +extern void ComparatorIntUnregister(unsigned long ulBase, + unsigned long ulComp); +extern void ComparatorIntEnable(unsigned long ulBase, unsigned long ulComp); +extern void ComparatorIntDisable(unsigned long ulBase, unsigned long ulComp); +extern tBoolean ComparatorIntStatus(unsigned long ulBase, unsigned long ulComp, + tBoolean bMasked); +extern void ComparatorIntClear(unsigned long ulBase, unsigned long ulComp); + +#ifdef __cplusplus +} +#endif + +#endif // __COMP_H__ diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/cpu.h b/Demo/CORTEX_LM3S811_GCC/hw_include/cpu.h new file mode 100644 index 000000000..688c52223 --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/cpu.h @@ -0,0 +1,40 @@ +//***************************************************************************** +// +// cpu.h - Prototypes for the CPU instruction wrapper functions. +// +// Copyright (c) 2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +#ifndef __CPU_H__ +#define __CPU_H__ + +//***************************************************************************** +// +// Prototypes. +// +//***************************************************************************** +extern void CPUcpsid(void); +extern void CPUcpsie(void); +extern void CPUwfi(void); + +#endif // __CPU_H__ diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/debug.h b/Demo/CORTEX_LM3S811_GCC/hw_include/debug.h new file mode 100644 index 000000000..e46e2a772 --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/debug.h @@ -0,0 +1,56 @@ +//***************************************************************************** +// +// debug.h - Macros for assisting debug of the driver library. +// +// Copyright (c) 2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +#ifndef __DEBUG_H__ +#define __DEBUG_H__ + +//***************************************************************************** +// +// Prototype for the function that is called when an invalid argument is passed +// to an API. This is only used when doing a DEBUG build. +// +//***************************************************************************** +extern void __error__(char *pcFilename, unsigned long ulLine); + +//***************************************************************************** +// +// The ASSERT macro, which does the actual assertion checking. Typically, this +// will be for procedure arguments. +// +//***************************************************************************** +#ifdef DEBUG +#define ASSERT(expr) { \ + if(!(expr)) \ + { \ + __error__(__FILE__, __LINE__); \ + } \ + } +#else +#define ASSERT(expr) +#endif + +#endif // __DEBUG_H__ diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/driverlib.r79 b/Demo/CORTEX_LM3S811_GCC/hw_include/driverlib.r79 new file mode 100644 index 0000000000000000000000000000000000000000..074f82f1209c2c2e29d2e3db8dfc459d5fcfd317 GIT binary patch literal 134217 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

wk2hg zvXHmY=l^q#hXf> (ulAddress / FLASH_PROTECT_SIZE)) & + FLASH_FMP_BLOCK_0) << 1) | + ((ulFMPPE >> (ulAddress / FLASH_PROTECT_SIZE)) & FLASH_FMP_BLOCK_0)) + { + // + // This block is marked as execute only (i.e. it can not be erased or + // programmed, and the only reads allowed are via the instruction fecth + // interface). + // + case 0: + case 1: + { + return(FlashExecuteOnly); + } + + // + // This block is marked as read only (i.e. it can not be erased or + // programmed). + // + case 2: + { + return(FlashReadOnly); + } + + // + // This block is read/write; it can be read, erased, and programmed. + // + case 3: + default: + { + return(FlashReadWrite); + } + } +} +#endif + +//***************************************************************************** +// +//! Sets the protection setting for a block of flash. +//! +//! \param ulAddress is the start address of the flash block to be protected. +//! \param eProtect is the protection to be applied to the block. Can be one +//! of \b FlashReadWrite, \b FlashReadOnly, or \b FlashExecuteOnly. +//! +//! This function will set the protection for the specified 2 kB block of +//! flash. Blocks which are read/write can be made read-only or execute-only. +//! Blocks which are read-only can be made execute-only. Blocks which are +//! execute-only cannot have their protection modified. Attempts to make the +//! block protection less stringent (i.e. read-only to read/write) will result +//! in a failure (and be prevented by the hardware). +//! +//! Changes to the flash protection are maintained only until the next reset. +//! This allows the application to be executed in the desired flash protection +//! environment to check for inappropriate flash access (via the flash +//! interrupt). To make the flash protection permanent, use the +//! FlashProtectSave() function. +//! +//! \return Returns 0 on success, or -1 if an invalid address or an invalid +//! protection was specified. +// +//***************************************************************************** +#if defined(GROUP_protectset) || defined(BUILD_ALL) || defined(DOXYGEN) +long +FlashProtectSet(unsigned long ulAddress, tFlashProtection eProtect) +{ + unsigned long ulProtectRE, ulProtectPE; + + // + // Check the argument. + // + ASSERT(!(ulAddress & (FLASH_PROTECT_SIZE - 1))); + ASSERT((eProtect == FlashReadWrite) || (eProtect == FlashReadOnly) || + (eProtect == FlashExecuteOnly)); + + // + // Convert the address into a block number. + // + ulAddress /= FLASH_PROTECT_SIZE; + + // + // Get the current protection. + // + ulProtectRE = HWREG(FLASH_FMPRE); + ulProtectPE = HWREG(FLASH_FMPPE); + + // + // Set the protection based on the requested proection. + // + switch(eProtect) + { + // + // Make this block execute only. + // + case FlashExecuteOnly: + { + // + // Turn off the read and program bits for this block. + // + ulProtectRE &= ~(FLASH_FMP_BLOCK_0 << ulAddress); + ulProtectPE &= ~(FLASH_FMP_BLOCK_0 << ulAddress); + + // + // We're done handling this protection. + // + break; + } + + // + // Make this block read only. + // + case FlashReadOnly: + { + // + // The block can not be made read only if it is execute only. + // + if(((ulProtectRE >> ulAddress) & FLASH_FMP_BLOCK_0) != + FLASH_FMP_BLOCK_0) + { + return(-1); + } + + // + // Make this block read only. + // + ulProtectPE &= ~(FLASH_FMP_BLOCK_0 << ulAddress); + + // + // We're done handling this protection. + // + break; + } + + // + // Make this block read/write. + // + case FlashReadWrite: + default: + { + // + // The block can not be made read/write if it is not already + // read/write. + // + if((((ulProtectRE >> ulAddress) & FLASH_FMP_BLOCK_0) != + FLASH_FMP_BLOCK_0) || + (((ulProtectPE >> ulAddress) & FLASH_FMP_BLOCK_0) != + FLASH_FMP_BLOCK_0)) + { + return(-1); + } + + // + // The block is already read/write, so there is nothing to do. + // + return(0); + } + } + + // + // Set the new protection. + // + HWREG(FLASH_FMPRE) = ulProtectRE; + HWREG(FLASH_FMPPE) = ulProtectPE; + + // + // Success. + // + return(0); +} +#endif + +//***************************************************************************** +// +//! Saves the flash protection settings. +//! +//! This function will make the currently programmed flash protection settings +//! permanent. This is a non-reversible operation; a chip reset or power cycle +//! will not change the flash protection. +//! +//! This function will not return until the protection has been saved. +//! +//! \return Returns 0 on success, or -1 if a hardware error is encountered. +// +//***************************************************************************** +#if defined(GROUP_protectsave) || defined(BUILD_ALL) || defined(DOXYGEN) +long +FlashProtectSave(void) +{ + // + // Tell the flash controller to write the flash read protection register. + // + HWREG(FLASH_FMA) = 0; + HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_COMT; + + // + // Wait until the write has completed. + // + while(HWREG(FLASH_FMC) & FLASH_FMC_COMT) + { + } + + // + // Tell the flash controller to write the flash program protection + // register. + // + HWREG(FLASH_FMA) = 1; + HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_COMT; + + // + // Wait until the write has completed. + // + while(HWREG(FLASH_FMC) & FLASH_FMC_COMT) + { + } + + // + // Success. + // + return(0); +} +#endif + +//***************************************************************************** +// +//! Registers an interrupt handler for the flash interrupt. +//! +//! \param pfnHandler is a pointer to the function to be called when the flash +//! interrupt occurs. +//! +//! This sets the handler to be called when the flash interrupt occurs. The +//! flash controller can generate an interrupt when an invalid flash access +//! occurs, such as trying to program or erase a read-only block, or trying to +//! read from an execute-only block. It can also generate an interrupt when a +//! program or erase operation has completed. The interrupt will be +//! automatically enabled when the handler is registered. +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intregister) || defined(BUILD_ALL) || defined(DOXYGEN) +void +FlashIntRegister(void (*pfnHandler)(void)) +{ + // + // Register the interrupt handler, returning an error if an error occurs. + // + IntRegister(INT_FLASH, pfnHandler); + + // + // Enable the flash interrupt. + // + IntEnable(INT_FLASH); +} +#endif + +//***************************************************************************** +// +//! Unregisters the interrupt handler for the flash interrupt. +//! +//! This function will clear the handler to be called when the flash interrupt +//! occurs. This will also mask off the interrupt in the interrupt controller +//! so that the interrupt handler is no longer called. +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intunregister) || defined(BUILD_ALL) || defined(DOXYGEN) +void +FlashIntUnregister(void) +{ + // + // Disable the interrupt. + // + IntDisable(INT_FLASH); + + // + // Unregister the interrupt handler. + // + IntUnregister(INT_FLASH); +} +#endif + +//***************************************************************************** +// +//! Enables individual flash controller interrupt sources. +//! +//! \param ulIntFlags is a bit mask of the interrupt sources to be enabled. +//! Can be any of the \b FLASH_FCIM_PROGRAM or \b FLASH_FCIM_ACCESS values. +//! +//! Enables the indicated flash controller interrupt sources. Only the sources +//! that are enabled can be reflected to the processor interrupt; disabled +//! sources have no effect on the processor. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intenable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +FlashIntEnable(unsigned long ulIntFlags) +{ + // + // Enable the specified interrupts. + // + HWREG(FLASH_FCIM) |= ulIntFlags; +} +#endif + +//***************************************************************************** +// +//! Disables individual flash controller interrupt sources. +//! +//! \param ulIntFlags is a bit mask of the interrupt sources to be disabled. +//! Can be any of the \b FLASH_FCIM_PROGRAM or \b FLASH_FCIM_ACCESS values. +//! +//! Disables the indicated flash controller interrupt sources. Only the +//! sources that are enabled can be reflected to the processor interrupt; +//! disabled sources have no effect on the processor. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intdisable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +FlashIntDisable(unsigned long ulIntFlags) +{ + // + // Disable the specified interrupts. + // + HWREG(FLASH_FCIM) &= ~(ulIntFlags); +} +#endif + +//***************************************************************************** +// +//! Gets the current interrupt status. +//! +//! \param bMasked is false if the raw interrupt status is required and true if +//! the masked interrupt status is required. +//! +//! This returns the interrupt status for the flash controller. Either the raw +//! interrupt status or the status of interrupts that are allowed to reflect to +//! the processor can be returned. +//! +//! \return The current interrupt status, enumerated as a bit field of +//! \b FLASH_FCMISC_PROGRAM and \b FLASH_FCMISC_ACCESS. +// +//***************************************************************************** +#if defined(GROUP_intgetstatus) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +FlashIntGetStatus(tBoolean bMasked) +{ + // + // Return either the interrupt status or the raw interrupt status as + // requested. + // + if(bMasked) + { + return(HWREG(FLASH_FCMISC)); + } + else + { + return(HWREG(FLASH_FCRIS)); + } +} +#endif + +//***************************************************************************** +// +//! Clears flash controller interrupt sources. +//! +//! \param ulIntFlags is the bit mask of the interrupt sources to be cleared. +//! Can be any of the \b FLASH_FCMISC_PROGRAM or \b FLASH_FCMISC_ACCESS +//! values. +//! +//! The specified flash controller interrupt sources are cleared, so that they +//! no longer assert. This must be done in the interrupt handler to keep it +//! from being called again immediately upon exit. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intclear) || defined(BUILD_ALL) || defined(DOXYGEN) +void +FlashIntClear(unsigned long ulIntFlags) +{ + // + // Clear the flash interrupt. + // + HWREG(FLASH_FCMISC) = ulIntFlags; +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/flash.h b/Demo/CORTEX_LM3S811_GCC/hw_include/flash.h new file mode 100644 index 000000000..9c41dda4f --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/flash.h @@ -0,0 +1,75 @@ +//***************************************************************************** +// +// flash.h - Prototypes for the flash driver. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +#ifndef __FLASH_H__ +#define __FLASH_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// Values that can be passed to FlashProtectSet(), and returned by +// FlashProtectGet(). +// +//***************************************************************************** +typedef enum +{ + FlashReadWrite, // Flash can be read and written + FlashReadOnly, // Flash can only be read + FlashExecuteOnly // Flash can only be executed +} +tFlashProtection; + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** +extern unsigned long FlashUsecGet(void); +extern void FlashUsecSet(unsigned long ulClocks); +extern long FlashErase(unsigned long ulAddress); +extern long FlashProgram(unsigned long *pulData, unsigned long ulAddress, + unsigned long ulCount); +extern tFlashProtection FlashProtectGet(unsigned long ulAddress); +extern long FlashProtectSet(unsigned long ulAddress, + tFlashProtection eProtect); +extern long FlashProtectSave(void); +extern void FlashIntRegister(void (*pfnHandler)(void)); +extern void FlashIntUnregister(void); +extern void FlashIntEnable(unsigned long ulIntFlags); +extern void FlashIntDisable(unsigned long ulIntFlags); +extern unsigned long FlashIntGetStatus(tBoolean bMasked); +extern void FlashIntClear(unsigned long ulIntFlags); + +#ifdef __cplusplus +} +#endif + +#endif // __FLASH_H__ diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/gpio.c b/Demo/CORTEX_LM3S811_GCC/hw_include/gpio.c new file mode 100644 index 000000000..a49602e9b --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/gpio.c @@ -0,0 +1,1103 @@ +//***************************************************************************** +// +// gpio.c - API for GPIO ports +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +//***************************************************************************** +// +//! \addtogroup gpio_api +//! @{ +// +//***************************************************************************** + +#include "../hw_gpio.h" +#include "../hw_ints.h" +#include "../hw_memmap.h" +#include "../hw_types.h" +#include "debug.h" +#include "gpio.h" +#include "interrupt.h" + +//***************************************************************************** +// +//! \internal +//! Get GPIO interrupt number. +//! +//! \param ulPort base address of the selected GPIO port +//! +//! Given a GPIO base address, returns the corresponding interrupt number. +//! +//! \return Returns a GPIO interrupt number, or -1 if \e ulPort is invalid. +// +//***************************************************************************** +#if defined(GROUP_getintnumber) || defined(BUILD_ALL) +long +GPIOGetIntNumber(unsigned long ulPort) +{ + unsigned int ulInt; + + // + // Determine the GPIO interrupt number for the given module. + // + switch(ulPort) + { + case GPIO_PORTA_BASE: + { + ulInt = INT_GPIOA; + break; + } + + case GPIO_PORTB_BASE: + { + ulInt = INT_GPIOB; + break; + } + + case GPIO_PORTC_BASE: + { + ulInt = INT_GPIOC; + break; + } + + case GPIO_PORTD_BASE: + { + ulInt = INT_GPIOD; + break; + } + + case GPIO_PORTE_BASE: + { + ulInt = INT_GPIOE; + break; + } + + default: + { + return(-1); + } + } + + // + // Return GPIO interrupt number. + // + return(ulInt); +} +#else +extern long GPIOGetIntNumber(unsigned long ulPort); +#endif + +//***************************************************************************** +// +//! Sets the direction and mode of the specified pins of the selected +//! GPIO port. +//! +//! \param ulPort base address of the selected GPIO port +//! \param ucPins bit-packed representation of the specified pins +//! \param ulPinIO pin direction and/or mode +//! +//! This function will set the specified pins on the selected GPIO port +//! as either an input or output under software control, or it will set the +//! pin to be under hardware control. +//! +//! The parameter \e ulPinIO is an enumerated data type that can be one of +//! the following values: +//! +//! - \b GPIO_DIR_MODE_IN +//! - \b GPIO_DIR_MODE_OUT +//! - \b GPIO_DIR_MODE_HW +//! +//! where \b GPIO_DIR_MODE_IN specifies that the pin will be programmed as +//! a software controlled input, \b GPIO_DIR_MODE_OUT specifies that the pin +//! will be programmed as a software controlled output, and +//! \b GPIO_DIR_MODE_HW specifies that the pin will be placed under +//! hardware control. +//! +//! The pins are specified using a bit-packed byte, where each bit that is +//! set identifies the pin to be accessed, and where bit 0 of the byte +//! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, etc. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_dirmodeset) || defined(BUILD_ALL) || defined(DOXYGEN) +void +GPIODirModeSet(unsigned long ulPort, unsigned char ucPins, + unsigned long ulPinIO) +{ + // + // Check the arguments. + // + ASSERT((ulPort == GPIO_PORTA_BASE) || (ulPort == GPIO_PORTB_BASE) || + (ulPort == GPIO_PORTC_BASE) || (ulPort == GPIO_PORTD_BASE) || + (ulPort == GPIO_PORTE_BASE)); + ASSERT((ulPinIO == GPIO_DIR_MODE_IN) || (ulPinIO == GPIO_DIR_MODE_OUT) || + (ulPinIO == GPIO_DIR_MODE_HW)); + + // + // Set the pin direction and mode. + // + HWREG(ulPort + GPIO_O_DIR) = ((ulPinIO & 1) ? + (HWREG(ulPort + GPIO_O_DIR) | ucPins) : + (HWREG(ulPort + GPIO_O_DIR) & ~(ucPins))); + HWREG(ulPort + GPIO_O_AFSEL) = ((ulPinIO & 2) ? + (HWREG(ulPort + GPIO_O_AFSEL) | ucPins) : + (HWREG(ulPort + GPIO_O_AFSEL) & + ~(ucPins))); +} +#endif + +//***************************************************************************** +// +//! Gets the direction and mode of a specified pin of the selected +//! GPIO port. +//! +//! \param ulPort base address of the selected GPIO port +//! \param ucPin pin number of the specified pin, relative to the selected +//! GPIO port. +//! +//! This function gets the direction and control mode for a specified pin on +//! the selected GPIO port. The pin can be configured as either an input or +//! output under software control, or it can be under hardware control. The +//! type of control and direction are returned as an enumerated data type. +//! +//! \return Returns one of the enumerated data types described for +//! GPIODirModeSet(). +// +//***************************************************************************** +#if defined(GROUP_dirmodeget) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +GPIODirModeGet(unsigned long ulPort, unsigned char ucPin) +{ + unsigned long ulDir, ulAFSEL; + + // + // Check the arguments. + // + ASSERT((ulPort == GPIO_PORTA_BASE) || (ulPort == GPIO_PORTB_BASE) || + (ulPort == GPIO_PORTC_BASE) || (ulPort == GPIO_PORTD_BASE) || + (ulPort == GPIO_PORTE_BASE)); + ASSERT(ucPin < 8); + + // + // Convert from a pin number to a bit position. + // + ucPin = 1 << ucPin; + + // + // Return the pin direction and mode. + // + ulDir = HWREG(ulPort + GPIO_O_DIR); + ulAFSEL = HWREG(ulPort + GPIO_O_AFSEL); + return(((ulDir & ucPin) ? 1 : 0) | ((ulAFSEL & ucPin) ? 2 : 0)); +} +#endif + +//***************************************************************************** +// +//! Sets the interrupt type for the specified pins of the selected GPIO +//! port. +//! +//! \param ulPort base address of the selected GPIO port +//! \param ucPins bit-packed representation of the specified pins +//! \param ulIntType specifies the type of interrupt trigger mechanism +//! +//! This function sets up the various interrupt trigger mechanisms for the +//! specified pins on the selected GPIO port. +//! +//! The parameter \e ulIntType is an enumerated data type that can be one of +//! the following values: +//! +//! - \b GPIO_FALLING_EDGE +//! - \b GPIO_RISING_EDGE +//! - \b GPIO_BOTH_EDGES +//! - \b GPIO_LOW_LEVEL +//! - \b GPIO_HIGH_LEVEL +//! +//! where the different values describe the interrupt detection mechanism +//! (edge or level) and the particular triggering event (falling, rising, +//! or both edges for edge detect, low or high for level detect). +//! +//! The pins are specified using a bit-packed byte, where each bit that is +//! set identifies the pin to be accessed, and where bit 0 of the byte +//! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, etc. +//! +//! \note In order to avoid any spurious interrupts, the user must +//! ensure that the GPIO inputs remain stable for the duration of +//! this function. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_inttypeset) || defined(BUILD_ALL) || defined(DOXYGEN) +void +GPIOIntTypeSet(unsigned long ulPort, unsigned char ucPins, + unsigned long ulIntType) +{ + // + // Check the arguments. + // + ASSERT((ulPort == GPIO_PORTA_BASE) || (ulPort == GPIO_PORTB_BASE) || + (ulPort == GPIO_PORTC_BASE) || (ulPort == GPIO_PORTD_BASE) || + (ulPort == GPIO_PORTE_BASE)); + ASSERT((ulIntType == GPIO_FALLING_EDGE) || + (ulIntType == GPIO_RISING_EDGE) || + (ulIntType == GPIO_BOTH_EDGES) || + (ulIntType == GPIO_LOW_LEVEL) || + (ulIntType == GPIO_HIGH_LEVEL)); + + // + // Set the pin interrupt type. + // + HWREG(ulPort + GPIO_O_IBE) = ((ulIntType & 1) ? + (HWREG(ulPort + GPIO_O_IBE) | ucPins) : + (HWREG(ulPort + GPIO_O_IBE) & ~(ucPins))); + HWREG(ulPort + GPIO_O_IS) = ((ulIntType & 2) ? + (HWREG(ulPort + GPIO_O_IS) | ucPins) : + (HWREG(ulPort + GPIO_O_IS) & ~(ucPins))); + HWREG(ulPort + GPIO_O_IEV) = ((ulIntType & 4) ? + (HWREG(ulPort + GPIO_O_IEV) | ucPins) : + (HWREG(ulPort + GPIO_O_IEV) & ~(ucPins))); +} +#endif + +//***************************************************************************** +// +//! Gets the interrupt type for the specified pin of the selected GPIO +//! port. +//! +//! \param ulPort base address of the selected GPIO port +//! \param ucPin pin number of the specified pin, relative to the selected +//! GPIO port. +//! +//! This function gets the interrupt type for a specified pin on the selected +//! GPIO port. The pin can be configured as a falling edge, rising edge, or +//! both edge detected interrupt, or it can be configured as a low level or +//! high level detected interrupt. The type of interrupt detection mechanism +//! is returned as an enumerated data type. +//! +//! \return Returns one of the enumerated data types described for +//! GPIOIntTypeSet(). +// +//***************************************************************************** +#if defined(GROUP_inttypeget) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +GPIOIntTypeGet(unsigned long ulPort, unsigned char ucPin) +{ + unsigned long ulIBE, ulIS, ulIEV; + + // + // Check the arguments. + // + ASSERT((ulPort == GPIO_PORTA_BASE) || (ulPort == GPIO_PORTB_BASE) || + (ulPort == GPIO_PORTC_BASE) || (ulPort == GPIO_PORTD_BASE) || + (ulPort == GPIO_PORTE_BASE)); + ASSERT(ucPin < 8); + + // + // Convert from a pin number to a bit position. + // + ucPin = 1 << ucPin; + + // + // Return the pin interrupt type. + // + ulIBE = HWREG(ulPort + GPIO_O_IBE); + ulIS = HWREG(ulPort + GPIO_O_IS); + ulIEV = HWREG(ulPort + GPIO_O_IEV); + return(((ulIBE & ucPin) ? 1 : 0) | ((ulIS & ucPin) ? 2 : 0) | + ((ulIEV & ucPin) ? 4 : 0)); +} +#endif + +//***************************************************************************** +// +//! Sets the pad configuration for the specified pins of the selected GPIO +//! port. +//! +//! \param ulPort is the base address of the GPIO port. +//! \param ucPins bit-packed representation of the specified pins. +//! \param ulStrength specifies the output drive strength. +//! \param ulPinType specifies the pin type. +//! +//! This function sets the drive strength and type for the specified pins +//! on the selected GPIO port. For pins configured as input ports, the +//! pad is configured as requested, but the only real effect on the input +//! is the configuration of the pull-up or pull-down termination. +//! +//! The parameter \e ulStrength can be one of the following values: +//! +//! - \b GPIO_STRENGTH_2MA +//! - \b GPIO_STRENGTH_4MA +//! - \b GPIO_STRENGTH_8MA +//! - \b GPIO_STRENGTH_8MA_SC +//! +//! where \b GPIO_STRENGTH_xMA specifies either 2, 4, or 8 mA output drive +//! strength, and \b GPIO_OUT_STRENGTH_8MA_SC specifies 8 mA output drive with +//! slew control. +//! +//! The parameter \e ulPinType can be one of the following values: +//! +//! - \b GPIO_PIN_TYPE_STD +//! - \b GPIO_PIN_TYPE_STD_WPU +//! - \b GPIO_PIN_TYPE_STD_WPD +//! - \b GPIO_PIN_TYPE_OD +//! - \b GPIO_PIN_TYPE_OD_WPU +//! - \b GPIO_PIN_TYPE_OD_WPD +//! - \b GPIO_PIN_TYPE_ANALOG +//! +//! where \b GPIO_PIN_TYPE_STD* specifies a push-pull pin, \b GPIO_PIN_TYPE_OD* +//! specifies an open-drain pin, \b *_WPU specifies a weak pull-up, \b *_WPD +//! specifies a weak pull-down, and \b GPIO_PIN_TYPE_ANALOG specifies an +//! analog input (for the comparators). +//! +//! The pins are specified using a bit-packed byte, where each bit that is +//! set identifies the pin to be accessed, and where bit 0 of the byte +//! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, etc. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_padconfigset) || defined(BUILD_ALL) || defined(DOXYGEN) +void +GPIOPadConfigSet(unsigned long ulPort, unsigned char ucPins, + unsigned long ulStrength, unsigned long ulPinType) +{ + // + // Check the arguments. + // + ASSERT((ulPort == GPIO_PORTA_BASE) || (ulPort == GPIO_PORTB_BASE) || + (ulPort == GPIO_PORTC_BASE) || (ulPort == GPIO_PORTD_BASE) || + (ulPort == GPIO_PORTE_BASE)); + ASSERT((ulStrength == GPIO_STRENGTH_2MA) || + (ulStrength == GPIO_STRENGTH_4MA) || + (ulStrength == GPIO_STRENGTH_8MA) || + (ulStrength == GPIO_STRENGTH_8MA_SC)); + ASSERT((ulPinType == GPIO_PIN_TYPE_STD) || + (ulPinType == GPIO_PIN_TYPE_STD_WPU) || + (ulPinType == GPIO_PIN_TYPE_STD_WPD) || + (ulPinType == GPIO_PIN_TYPE_OD) || + (ulPinType == GPIO_PIN_TYPE_OD_WPU) || + (ulPinType == GPIO_PIN_TYPE_OD_WPD) || + (ulPinType == GPIO_PIN_TYPE_ANALOG)) + + // + // Set the output drive strength. + // + HWREG(ulPort + GPIO_O_DR2R) = ((ulStrength & 1) ? + (HWREG(ulPort + GPIO_O_DR2R) | ucPins) : + (HWREG(ulPort + GPIO_O_DR2R) & ~(ucPins))); + HWREG(ulPort + GPIO_O_DR4R) = ((ulStrength & 2) ? + (HWREG(ulPort + GPIO_O_DR4R) | ucPins) : + (HWREG(ulPort + GPIO_O_DR4R) & ~(ucPins))); + HWREG(ulPort + GPIO_O_DR8R) = ((ulStrength & 4) ? + (HWREG(ulPort + GPIO_O_DR8R) | ucPins) : + (HWREG(ulPort + GPIO_O_DR8R) & ~(ucPins))); + HWREG(ulPort + GPIO_O_SLR) = ((ulStrength & 8) ? + (HWREG(ulPort + GPIO_O_SLR) | ucPins) : + (HWREG(ulPort + GPIO_O_SLR) & ~(ucPins))); + + // + // Set the pin type. + // + HWREG(ulPort + GPIO_O_ODR) = ((ulPinType & 1) ? + (HWREG(ulPort + GPIO_O_ODR) | ucPins) : + (HWREG(ulPort + GPIO_O_ODR) & ~(ucPins))); + HWREG(ulPort + GPIO_O_PUR) = ((ulPinType & 2) ? + (HWREG(ulPort + GPIO_O_PUR) | ucPins) : + (HWREG(ulPort + GPIO_O_PUR) & ~(ucPins))); + HWREG(ulPort + GPIO_O_PDR) = ((ulPinType & 4) ? + (HWREG(ulPort + GPIO_O_PDR) | ucPins) : + (HWREG(ulPort + GPIO_O_PDR) & ~(ucPins))); + HWREG(ulPort + GPIO_O_DEN) = ((ulPinType & 8) ? + (HWREG(ulPort + GPIO_O_DEN) | ucPins) : + (HWREG(ulPort + GPIO_O_DEN) & ~(ucPins))); +} +#endif + +//***************************************************************************** +// +//! Gets the pad configuration for the specified pin of the selected GPIO +//! port. +//! +//! \param ulPort base address of the selected GPIO port +//! \param ucPin pin number of the specified pin, relative to the selected +//! GPIO port. +//! \param pulStrength pointer to storage for the output drive strength +//! \param pulPinType pointer to storage for the output drive type +//! +//! This function gets the pad configuration for a specified pin on the +//! selected GPIO port. The values returned in \e eStrength and \e eOutType +//! correspond to the values used in GPIOPadConfigSet(). This function also +//! works for pins configured as input pins; however, the only meaningful +//! data returned is whether the pin is terminated with a pull-up or +//! down resistor. +//! +//! \return None +// +//***************************************************************************** +#if defined(GROUP_padconfigget) || defined(BUILD_ALL) || defined(DOXYGEN) +void +GPIOPadConfigGet(unsigned long ulPort, unsigned char ucPin, + unsigned long *pulStrength, unsigned long *pulPinType) +{ + unsigned long ulTemp1, ulTemp2, ulTemp3, ulTemp4; + + // + // Check the arguments. + // + ASSERT((ulPort == GPIO_PORTA_BASE) || (ulPort == GPIO_PORTB_BASE) || + (ulPort == GPIO_PORTC_BASE) || (ulPort == GPIO_PORTD_BASE) || + (ulPort == GPIO_PORTE_BASE)); + ASSERT(ucPin < 8); + + // + // Convert from a pin number to a bit position. + // + ucPin = (1 << ucPin); + + // + // Get the drive strength for this pin. + // + ulTemp1 = HWREG(ulPort + GPIO_O_DR2R); + ulTemp2 = HWREG(ulPort + GPIO_O_DR4R); + ulTemp3 = HWREG(ulPort + GPIO_O_DR8R); + ulTemp4 = HWREG(ulPort + GPIO_O_SLR); + *pulStrength = (((ulTemp1 & ucPin) ? 1 : 0) | ((ulTemp2 & ucPin) ? 2 : 0) | + ((ulTemp3 & ucPin) ? 4 : 0) | ((ulTemp4 & ucPin) ? 8 : 0)); + + // + // Get the pin type. + // + ulTemp1 = HWREG(ulPort + GPIO_O_ODR); + ulTemp2 = HWREG(ulPort + GPIO_O_PUR); + ulTemp3 = HWREG(ulPort + GPIO_O_PDR); + ulTemp4 = HWREG(ulPort + GPIO_O_DEN); + *pulPinType = (((ulTemp1 & ucPin) ? 1 : 0) | ((ulTemp2 & ucPin) ? 2 : 0) | + ((ulTemp3 & ucPin) ? 4 : 0) | ((ulTemp4 & ucPin) ? 8 : 0)); +} +#endif + +//***************************************************************************** +// +//! Enables interrupts for the specified pins of the selected GPIO port. +//! +//! \param ulPort base address of the selected GPIO port +//! \param ucPins bit-packed representation of the specified pins +//! +//! Unmasks the interrupt for the specified pins. +//! +//! The pins are specified using a bit-packed byte, where each bit that is +//! set identifies the pin to be accessed, and where bit 0 of the byte +//! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, etc. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_pinintenable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +GPIOPinIntEnable(unsigned long ulPort, unsigned char ucPins) +{ + // + // Check the arguments. + // + ASSERT((ulPort == GPIO_PORTA_BASE) || (ulPort == GPIO_PORTB_BASE) || + (ulPort == GPIO_PORTC_BASE) || (ulPort == GPIO_PORTD_BASE) || + (ulPort == GPIO_PORTE_BASE)); + + // + // Enable the interrupts. + // + HWREG(ulPort + GPIO_O_IM) |= ucPins; +} +#endif + +//***************************************************************************** +// +//! Disables interrupts for the specified pins of the selected GPIO port. +//! +//! \param ulPort base address of the selected GPIO port +//! \param ucPins bit-packed representation of the specified pins +//! +//! Masks the interrupt for the specified pins. +//! +//! The pins are specified using a bit-packed byte, where each bit that is +//! set identifies the pin to be accessed, and where bit 0 of the byte +//! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, etc. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_pinintdisable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +GPIOPinIntDisable(unsigned long ulPort, unsigned char ucPins) +{ + // + // Check the arguments. + // + ASSERT((ulPort == GPIO_PORTA_BASE) || (ulPort == GPIO_PORTB_BASE) || + (ulPort == GPIO_PORTC_BASE) || (ulPort == GPIO_PORTD_BASE) || + (ulPort == GPIO_PORTE_BASE)); + + // + // Disable the interrupts. + // + HWREG(ulPort + GPIO_O_IM) &= ~(ucPins); +} +#endif + +//***************************************************************************** +// +//! Gets interrupt status for all the pins of the selected GPIO port. +//! +//! \param ulPort base address of the selected GPIO port +//! \param bMasked specifies whether masked or raw interrupt +//! status is returned +//! +//! If \e bMasked is set as \b true, then the masked interrupt status is +//! returned; otherwise, the raw interrupt status will be returned. +//! +//! \return Returns a bit-packed byte, where each bit that is set identifies +//! an active masked or raw interrupt, and where bit 0 of the byte +//! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, etc. Bits +//! 31:8 should be ignored. +// +//***************************************************************************** +#if defined(GROUP_pinintstatus) || defined(BUILD_ALL) || defined(DOXYGEN) +long +GPIOPinIntStatus(unsigned long ulPort, tBoolean bMasked) +{ + // + // Check the arguments. + // + ASSERT((ulPort == GPIO_PORTA_BASE) || (ulPort == GPIO_PORTB_BASE) || + (ulPort == GPIO_PORTC_BASE) || (ulPort == GPIO_PORTD_BASE) || + (ulPort == GPIO_PORTE_BASE)); + + // + // Return the interrupt status. + // + if(bMasked) + { + return(HWREG(ulPort + GPIO_O_MIS)); + } + else + { + return(HWREG(ulPort + GPIO_O_RIS)); + } +} +#endif + +//***************************************************************************** +// +//! Clears the interrupt for the specified pins of the selected GPIO port. +//! +//! \param ulPort base address of the selected GPIO port +//! \param ucPins bit-packed representation of the specified pins +//! +//! Clears the interrupt for the specified pins. +//! +//! The pins are specified using a bit-packed byte, where each bit that is +//! set identifies the pin to be accessed, and where bit 0 of the byte +//! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, etc. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_pinintclear) || defined(BUILD_ALL) || defined(DOXYGEN) +void +GPIOPinIntClear(unsigned long ulPort, unsigned char ucPins) +{ + // + // Check the arguments. + // + ASSERT((ulPort == GPIO_PORTA_BASE) || (ulPort == GPIO_PORTB_BASE) || + (ulPort == GPIO_PORTC_BASE) || (ulPort == GPIO_PORTD_BASE) || + (ulPort == GPIO_PORTE_BASE)); + + // + // Clear the interrupts. + // + HWREG(ulPort + GPIO_O_ICR) = ucPins; +} +#endif + +//***************************************************************************** +// +//! Registers an interrupt handler for the selected GPIO port. +//! +//! \param ulPort base address of the selected GPIO port +//! \param pfIntHandler pointer to the GPIO port interrupt handling function +//! +//! This function will ensure that the interrupt handler specified by \e +//! pfIntHandler is called when an interrupt is detected from the selected +//! GPIO port. This function will also enable the corresponding GPIO +//! interrupt in the interrupt controller; individual pin interrupts and +//! interrupt sources must be enabled with GPIOPinIntEnable(). +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_portintregister) || defined(BUILD_ALL) || defined(DOXYGEN) +void +GPIOPortIntRegister(unsigned long ulPort, void (*pfIntHandler)(void)) +{ + // + // Check the arguments. + // + ASSERT((ulPort == GPIO_PORTA_BASE) || (ulPort == GPIO_PORTB_BASE) || + (ulPort == GPIO_PORTC_BASE) || (ulPort == GPIO_PORTD_BASE) || + (ulPort == GPIO_PORTE_BASE)); + + // + // Get the interrupt number associated with the specified GPIO. + // + ulPort = GPIOGetIntNumber(ulPort); + + // + // Register the interrupt handler. + // + IntRegister(ulPort, pfIntHandler); + + // + // Enable the GPIO interrupt. + // + IntEnable(ulPort); +} +#endif + +//***************************************************************************** +// +//! Removes an interrupt handler for the selected GPIO port. +//! +//! \param ulPort base address of the selected GPIO port +//! +//! This function will unregister the interrupt handler for the specified +//! GPIO port. This function will also disable the corresponding +//! GPIO port interrupt in the interrupt controller; individual GPIO interrupts +//! and interrupt sources must be disabled with GPIOPinIntDisable(). +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_portintunregister) || defined(BUILD_ALL) || defined(DOXYGEN) +void +GPIOPortIntUnregister(unsigned long ulPort) +{ + // + // Check the arguments. + // + ASSERT((ulPort == GPIO_PORTA_BASE) || (ulPort == GPIO_PORTB_BASE) || + (ulPort == GPIO_PORTC_BASE) || (ulPort == GPIO_PORTD_BASE) || + (ulPort == GPIO_PORTE_BASE)); + + // + // Get the interrupt number associated with the specified GPIO. + // + ulPort = GPIOGetIntNumber(ulPort); + + // + // Disable the GPIO interrupt. + // + IntDisable(ulPort); + + // + // Unregister the interrupt handler. + // + IntUnregister(ulPort); +} +#endif + +//***************************************************************************** +// +//! Reads the values present at the specified pins of the selected GPIO port. +//! +//! \param ulPort base address of the selected GPIO port +//! \param ucPins bit-packed representation of the specified pins +//! +//! The values at the specified pins are read, as specified by \e ucPins. +//! Values are returned for both input and output pins, and the value +//! for pins that are not specified by \e ucPins are set to 0. +//! +//! The pins are specified using a bit-packed byte, where each bit that is +//! set identifies the pin to be accessed, and where bit 0 of the byte +//! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, etc. +//! +//! \return Returns a bit-packed byte providing the state of the specified +//! pin, where bit 0 of the byte represents GPIO port pin 0, bit 1 represents +//! GPIO port pin 1, etc. Any bit that is not specified by \e ucPins +//! is returned as a 0. Bits 31:8 should be ignored. +// +//***************************************************************************** +#if defined(GROUP_pinread) || defined(BUILD_ALL) || defined(DOXYGEN) +long +GPIOPinRead(unsigned long ulPort, unsigned char ucPins) +{ + // + // Check the arguments. + // + ASSERT((ulPort == GPIO_PORTA_BASE) || (ulPort == GPIO_PORTB_BASE) || + (ulPort == GPIO_PORTC_BASE) || (ulPort == GPIO_PORTD_BASE) || + (ulPort == GPIO_PORTE_BASE)); + + // + // Return the pin value(s). + // + return(HWREG(ulPort + (GPIO_O_DATA + (ucPins << 2)))); +} +#endif + +//***************************************************************************** +// +//! Writes a value at the specified pins of the selected GPIO port. +//! +//! \param ulPort base address of the selected GPIO port +//! \param ucPins bit-packed representation of the specified pins +//! \param ucVal value to write to the specified pins +//! +//! Writes the corresponding bit values to the output pins specified +//! by \e ucPins. Writing to a pin configured as an input pin has no +//! effect. +//! +//! The pins are specified using a bit-packed byte, where each bit that is +//! set identifies the pin to be accessed, and where bit 0 of the byte +//! represents GPIO port pin 0, bit 1 represents GPIO port pin 1, etc. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_pinwrite) || defined(BUILD_ALL) || defined(DOXYGEN) +void +GPIOPinWrite(unsigned long ulPort, unsigned char ucPins, unsigned char ucVal) +{ + // + // Check the arguments. + // + ASSERT((ulPort == GPIO_PORTA_BASE) || (ulPort == GPIO_PORTB_BASE) || + (ulPort == GPIO_PORTC_BASE) || (ulPort == GPIO_PORTD_BASE) || + (ulPort == GPIO_PORTE_BASE)); + + // + // Write the pins. + // + HWREG(ulPort + (GPIO_O_DATA + (ucPins << 2))) = ucVal; +} +#endif + +//***************************************************************************** +// +//! Configures pin(s) for use as an analog comparator input. +//! +//! \param ulPort base address of the selected GPIO port +//! \param ucPins bit-packed representation of the specified pins +//! +//! The analog comparator input pins must be properly configured for the analog +//! comparator to function correctly. This function provides the proper +//! configuration for those pins. +//! +//! \note This cannot be used to turn any pin into an analog comparator input; +//! it only configures an analog comparator pin for proper operation. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_pintypecomparator) || defined(BUILD_ALL) || defined(DOXYGEN) +void +GPIOPinTypeComparator(unsigned long ulPort, unsigned char ucPins) +{ + // + // Check the arguments. + // + ASSERT((ulPort == GPIO_PORTA_BASE) || (ulPort == GPIO_PORTB_BASE) || + (ulPort == GPIO_PORTC_BASE) || (ulPort == GPIO_PORTD_BASE) || + (ulPort == GPIO_PORTE_BASE)); + + // + // Make the pin(s) be inputs. + // + GPIODirModeSet(ulPort, ucPins, GPIO_DIR_MODE_IN); + + // + // Set the pad(s) for analog operation. + // + GPIOPadConfigSet(ulPort, ucPins, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_ANALOG); +} +#endif + +//***************************************************************************** +// +//! Configures pin(s) for use by the I2C peripheral. +//! +//! \param ulPort base address of the selected GPIO port +//! \param ucPins bit-packed representation of the specified pins +//! +//! The I2C pins must be properly configured for the I2C peripheral to function +//! correctly. This function provides the proper configuration for those pins. +//! +//! \note This cannot be used to turn any pin into an I2C pin; it only +//! configures an I2C pin for proper operation. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_pintypei2c) || defined(BUILD_ALL) || defined(DOXYGEN) +void +GPIOPinTypeI2C(unsigned long ulPort, unsigned char ucPins) +{ + // + // Check the arguments. + // + ASSERT((ulPort == GPIO_PORTA_BASE) || (ulPort == GPIO_PORTB_BASE) || + (ulPort == GPIO_PORTC_BASE) || (ulPort == GPIO_PORTD_BASE) || + (ulPort == GPIO_PORTE_BASE)); + + // + // Make the pin(s) be peripheral controlled. + // + GPIODirModeSet(ulPort, ucPins, GPIO_DIR_MODE_HW); + + // + // Set the pad(s) for open-drain operation with a weak pull-up. + // + GPIOPadConfigSet(ulPort, ucPins, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_OD_WPU); +} +#endif + +//***************************************************************************** +// +//! Configures pin(s) for use by the PWM peripheral. +//! +//! \param ulPort base address of the selected GPIO port +//! \param ucPins bit-packed representation of the specified pins +//! +//! The PWM pins must be properly configured for the PWM peripheral to function +//! correctly. This function provides a typical configuration for those pins; +//! other configurations may work as well depending upon the board setup (for +//! example, using the on-chip pull-ups). +//! +//! \note This cannot be used to turn any pin into a PWM pin; it only +//! configures a PWM pin for proper operation. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_pintypepwm) || defined(BUILD_ALL) || defined(DOXYGEN) +void +GPIOPinTypePWM(unsigned long ulPort, unsigned char ucPins) +{ + // + // Check the arguments. + // + ASSERT((ulPort == GPIO_PORTA_BASE) || (ulPort == GPIO_PORTB_BASE) || + (ulPort == GPIO_PORTC_BASE) || (ulPort == GPIO_PORTD_BASE) || + (ulPort == GPIO_PORTE_BASE)); + + // + // Make the pin(s) be peripheral controlled. + // + GPIODirModeSet(ulPort, ucPins, GPIO_DIR_MODE_HW); + + // + // Set the pad(s) for standard push-pull operation. + // + GPIOPadConfigSet(ulPort, ucPins, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD); +} +#endif + +//***************************************************************************** +// +//! Configures pin(s) for use by the QEI peripheral. +//! +//! \param ulPort base address of the selected GPIO port +//! \param ucPins bit-packed representation of the specified pins +//! +//! The QEI pins must be properly configured for the QEI peripheral to function +//! correctly. This function provides a typical configuration for those pins; +//! other configurations may work as well depending upon the board setup (for +//! example, not using the on-chip pull-ups). +//! +//! \note This cannot be used to turn any pin into a QEI pin; it only +//! configures a QEI pin for proper operation. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_pintypeqei) || defined(BUILD_ALL) || defined(DOXYGEN) +void +GPIOPinTypeQEI(unsigned long ulPort, unsigned char ucPins) +{ + // + // Check the arguments. + // + ASSERT((ulPort == GPIO_PORTA_BASE) || (ulPort == GPIO_PORTB_BASE) || + (ulPort == GPIO_PORTC_BASE) || (ulPort == GPIO_PORTD_BASE) || + (ulPort == GPIO_PORTE_BASE)); + + // + // Make the pin(s) be peripheral controlled. + // + GPIODirModeSet(ulPort, ucPins, GPIO_DIR_MODE_HW); + + // + // Set the pad(s) for standard push-pull operation with a weak pull-up. + // + GPIOPadConfigSet(ulPort, ucPins, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU); +} +#endif + +//***************************************************************************** +// +//! Configures pin(s) for use by the SSI peripheral. +//! +//! \param ulPort base address of the selected GPIO port +//! \param ucPins bit-packed representation of the specified pins +//! +//! The SSI pins must be properly configured for the SSI peripheral to function +//! correctly. This function provides a typical configuration for those pins; +//! other configurations may work as well depending upon the board setup (for +//! example, using the on-chip pull-ups). +//! +//! \note This cannot be used to turn any pin into a SSI pin; it only +//! configures a SSI pin for proper operation. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_pintypessi) || defined(BUILD_ALL) || defined(DOXYGEN) +void +GPIOPinTypeSSI(unsigned long ulPort, unsigned char ucPins) +{ + // + // Check the arguments. + // + ASSERT((ulPort == GPIO_PORTA_BASE) || (ulPort == GPIO_PORTB_BASE) || + (ulPort == GPIO_PORTC_BASE) || (ulPort == GPIO_PORTD_BASE) || + (ulPort == GPIO_PORTE_BASE)); + + // + // Make the pin(s) be peripheral controlled. + // + GPIODirModeSet(ulPort, ucPins, GPIO_DIR_MODE_HW); + + // + // Set the pad(s) for standard push-pull operation. + // + GPIOPadConfigSet(ulPort, ucPins, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD); +} +#endif + +//***************************************************************************** +// +//! Configures pin(s) for use by the Timer peripheral. +//! +//! \param ulPort base address of the selected GPIO port +//! \param ucPins bit-packed representation of the specified pins +//! +//! The CCP pins must be properly configured for the timer peripheral to +//! function correctly. This function provides a typical configuration for +//! those pins; other configurations may work as well depending upon the board +//! setup (for example, using the on-chip pull-ups). +//! +//! \note This cannot be used to turn any pin into a timer pin; it only +//! configures a timer pin for proper operation. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_pintypetimer) || defined(BUILD_ALL) || defined(DOXYGEN) +void +GPIOPinTypeTimer(unsigned long ulPort, unsigned char ucPins) +{ + // + // Check the arguments. + // + ASSERT((ulPort == GPIO_PORTA_BASE) || (ulPort == GPIO_PORTB_BASE) || + (ulPort == GPIO_PORTC_BASE) || (ulPort == GPIO_PORTD_BASE) || + (ulPort == GPIO_PORTE_BASE)); + + // + // Make the pin(s) be peripheral controlled. + // + GPIODirModeSet(ulPort, ucPins, GPIO_DIR_MODE_HW); + + // + // Set the pad(s) for standard push-pull operation. + // + GPIOPadConfigSet(ulPort, ucPins, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD); +} +#endif + +//***************************************************************************** +// +//! Configures pin(s) for use by the UART peripheral. +//! +//! \param ulPort base address of the selected GPIO port +//! \param ucPins bit-packed representation of the specified pins +//! +//! The UART pins must be properly configured for the UART peripheral to +//! function correctly. This function provides a typical configuration for +//! those pins; other configurations may work as well depending upon the board +//! setup (for example, using the on-chip pull-ups). +//! +//! \note This cannot be used to turn any pin into a UART pin; it only +//! configures a UART pin for proper operation. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_pintypeuart) || defined(BUILD_ALL) || defined(DOXYGEN) +void +GPIOPinTypeUART(unsigned long ulPort, unsigned char ucPins) +{ + // + // Check the arguments. + // + ASSERT((ulPort == GPIO_PORTA_BASE) || (ulPort == GPIO_PORTB_BASE) || + (ulPort == GPIO_PORTC_BASE) || (ulPort == GPIO_PORTD_BASE) || + (ulPort == GPIO_PORTE_BASE)); + + // + // Make the pin(s) be peripheral controlled. + // + GPIODirModeSet(ulPort, ucPins, GPIO_DIR_MODE_HW); + + // + // Set the pad(s) for standard push-pull operation. + // + GPIOPadConfigSet(ulPort, ucPins, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD); +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/gpio.h b/Demo/CORTEX_LM3S811_GCC/hw_include/gpio.h new file mode 100644 index 000000000..88d657223 --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/gpio.h @@ -0,0 +1,137 @@ +//***************************************************************************** +// +// gpio.h - Defines and Macros for GPIO API. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +#ifndef __GPIO_H__ +#define __GPIO_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// The following values define the bit field for the ucPins argument to several +// of the APIs. +// +//***************************************************************************** +#define GPIO_PIN_0 0x00000001 // GPIO pin 0 +#define GPIO_PIN_1 0x00000002 // GPIO pin 1 +#define GPIO_PIN_2 0x00000004 // GPIO pin 2 +#define GPIO_PIN_3 0x00000008 // GPIO pin 3 +#define GPIO_PIN_4 0x00000010 // GPIO pin 4 +#define GPIO_PIN_5 0x00000020 // GPIO pin 5 +#define GPIO_PIN_6 0x00000040 // GPIO pin 6 +#define GPIO_PIN_7 0x00000080 // GPIO pin 7 + +//***************************************************************************** +// +// Values that can be passed to GPIODirModeSet as the ulPinIO parameter, and +// returned from GPIODirModeGet. +// +//***************************************************************************** +#define GPIO_DIR_MODE_IN 0x00000000 // Pin is a GPIO input +#define GPIO_DIR_MODE_OUT 0x00000001 // Pin is a GPIO output +#define GPIO_DIR_MODE_HW 0x00000002 // Pin is a peripheral function + +//***************************************************************************** +// +// Values that can be passed to GPIOIntTypeSet as the ulIntType parameter, and +// returned from GPIOIntTypeGet. +// +//***************************************************************************** +#define GPIO_FALLING_EDGE 0x00000000 // Interrupt on falling edge +#define GPIO_RISING_EDGE 0x00000004 // Interrupt on rising edge +#define GPIO_BOTH_EDGES 0x00000001 // Interrupt on both edges +#define GPIO_LOW_LEVEL 0x00000002 // Interrupt on low level +#define GPIO_HIGH_LEVEL 0x00000007 // Interrupt on high level + +//***************************************************************************** +// +// Values that can be passed to GPIOPadConfigSet as the ulStrength parameter, +// and returned by GPIOPadConfigGet in the *pulStrength parameter. +// +//***************************************************************************** +#define GPIO_STRENGTH_2MA 0x00000001 // 2mA drive strength +#define GPIO_STRENGTH_4MA 0x00000002 // 4mA drive strength +#define GPIO_STRENGTH_8MA 0x00000004 // 8mA drive strength +#define GPIO_STRENGTH_8MA_SC 0x0000000C // 8mA drive with slew rate control + +//***************************************************************************** +// +// Values that can be passed to GPIOPadConfigSet as the ulPadType parameter, +// and returned by GPIOPadConfigGet in the *pulPadType parameter. +// +//***************************************************************************** +#define GPIO_PIN_TYPE_STD 0x00000008 // Push-pull +#define GPIO_PIN_TYPE_STD_WPU 0x0000000A // Push-pull with weak pull-up +#define GPIO_PIN_TYPE_STD_WPD 0x0000000C // Push-pull with weak pull-down +#define GPIO_PIN_TYPE_OD 0x00000009 // Open-drain +#define GPIO_PIN_TYPE_OD_WPU 0x0000000B // Open-drain with weak pull-up +#define GPIO_PIN_TYPE_OD_WPD 0x0000000D // Open-drain with weak pull-down +#define GPIO_PIN_TYPE_ANALOG 0x00000000 // Analog comparator + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** +extern void GPIODirModeSet(unsigned long ulPort, unsigned char ucPins, + unsigned long ulPinIO); +extern unsigned long GPIODirModeGet(unsigned long ulPort, unsigned char ucPin); +extern void GPIOIntTypeSet(unsigned long ulPort, unsigned char ucPins, + unsigned long ulIntType); +extern unsigned long GPIOIntTypeGet(unsigned long ulPort, unsigned char ucPin); +extern void GPIOPadConfigSet(unsigned long ulPort, unsigned char ucPins, + unsigned long ulStrength, + unsigned long ulPadType); +extern void GPIOPadConfigGet(unsigned long ulPort, unsigned char ucPin, + unsigned long *pulStrength, + unsigned long *pulPadType); +extern void GPIOPinIntEnable(unsigned long ulPort, unsigned char ucPins); +extern void GPIOPinIntDisable(unsigned long ulPort, unsigned char ucPins); +extern long GPIOPinIntStatus(unsigned long ulPort, tBoolean bMasked); +extern void GPIOPinIntClear(unsigned long ulPort, unsigned char ucPins); +extern void GPIOPortIntRegister(unsigned long ulPort, + void (*pfIntHandler)(void)); +extern void GPIOPortIntUnregister(unsigned long ulPort); +extern long GPIOPinRead(unsigned long ulPort, unsigned char ucPins); +extern void GPIOPinWrite(unsigned long ulPort, unsigned char ucPins, + unsigned char ucVal); +extern void GPIOPinTypeComparator(unsigned long ulPort, unsigned char ucPins); +extern void GPIOPinTypeI2C(unsigned long ulPort, unsigned char ucPins); +extern void GPIOPinTypePWM(unsigned long ulPort, unsigned char ucPins); +extern void GPIOPinTypeQEI(unsigned long ulPort, unsigned char ucPins); +extern void GPIOPinTypeSSI(unsigned long ulPort, unsigned char ucPins); +extern void GPIOPinTypeTimer(unsigned long ulPort, unsigned char ucPins); +extern void GPIOPinTypeUART(unsigned long ulPort, unsigned char ucPins); + +#ifdef __cplusplus +} +#endif + +#endif // __GPIO_H__ diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/hw_adc.h b/Demo/CORTEX_LM3S811_GCC/hw_include/hw_adc.h new file mode 100644 index 000000000..022b9e963 --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/hw_adc.h @@ -0,0 +1,343 @@ +//***************************************************************************** +// +// hw_adc.h - Macros used when accessing the ADC hardware. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +#ifndef __HW_ADC_H__ +#define __HW_ADC_H__ + +//***************************************************************************** +// +// The following define the offsets of the ADC registers. +// +//***************************************************************************** +#define ADC_O_ACTSS 0x00000000 // Active sample register +#define ADC_O_RIS 0x00000004 // Raw interrupt status register +#define ADC_O_IM 0x00000008 // Interrupt mask register +#define ADC_O_ISC 0x0000000C // Interrupt status/clear register +#define ADC_O_OSTAT 0x00000010 // Overflow status register +#define ADC_O_EMUX 0x00000014 // Event multiplexer select reg. +#define ADC_O_USTAT 0x00000018 // Underflow status register +#define ADC_O_SSPRI 0x00000020 // Channel priority register +#define ADC_O_PSSI 0x00000028 // Processor sample initiate reg. +#define ADC_O_SAC 0x00000030 // Sample Averaging Control reg. +#define ADC_O_SSMUX0 0x00000040 // Multiplexer select 0 register +#define ADC_O_SSCTL0 0x00000044 // Sample sequence control 0 reg. +#define ADC_O_SSFIFO0 0x00000048 // Result FIFO 0 register +#define ADC_O_SSFSTAT0 0x0000004C // FIFO 0 status register +#define ADC_O_SSMUX1 0x00000060 // Multiplexer select 1 register +#define ADC_O_SSCTL1 0x00000064 // Sample sequence control 1 reg. +#define ADC_O_SSFIFO1 0x00000068 // Result FIFO 1 register +#define ADC_O_SSFSTAT1 0x0000006C // FIFO 1 status register +#define ADC_O_SSMUX2 0x00000080 // Multiplexer select 2 register +#define ADC_O_SSCTL2 0x00000084 // Sample sequence control 2 reg. +#define ADC_O_SSFIFO2 0x00000088 // Result FIFO 2 register +#define ADC_O_SSFSTAT2 0x0000008C // FIFO 2 status register +#define ADC_O_SSMUX3 0x000000A0 // Multiplexer select 3 register +#define ADC_O_SSCTL3 0x000000A4 // Sample sequence control 3 reg. +#define ADC_O_SSFIFO3 0x000000A8 // Result FIFO 3 register +#define ADC_O_SSFSTAT3 0x000000AC // FIFO 3 status register +#define ADC_O_TMLB 0x00000100 // Test mode loopback register + +//***************************************************************************** +// +// The following define the offsets of the ADC sequence registers. +// +//***************************************************************************** +#define ADC_O_SEQ 0x00000040 // Offset to the first sequence +#define ADC_O_SEQ_STEP 0x00000020 // Increment to the next sequence +#define ADC_O_X_SSMUX 0x00000000 // Multiplexer select register +#define ADC_O_X_SSCTL 0x00000004 // Sample sequence control register +#define ADC_O_X_SSFIFO 0x00000008 // Result FIFO register +#define ADC_O_X_SSFSTAT 0x0000000C // FIFO status register + +//***************************************************************************** +// +// The following define the bit fields in the ADC_ACTSS register. +// +//***************************************************************************** +#define ADC_ACTSS_ASEN3 0x00000008 // Sample sequence 3 enable +#define ADC_ACTSS_ASEN2 0x00000004 // Sample sequence 2 enable +#define ADC_ACTSS_ASEN1 0x00000002 // Sample sequence 1 enable +#define ADC_ACTSS_ASEN0 0x00000001 // Sample sequence 0 enable + +//***************************************************************************** +// +// The following define the bit fields in the ADC_RIS register. +// +//***************************************************************************** +#define ADC_RIS_INR3 0x00000008 // Sample sequence 3 interrupt +#define ADC_RIS_INR2 0x00000004 // Sample sequence 2 interrupt +#define ADC_RIS_INR1 0x00000002 // Sample sequence 1 interrupt +#define ADC_RIS_INR0 0x00000001 // Sample sequence 0 interrupt + +//***************************************************************************** +// +// The following define the bit fields in the ADC_IM register. +// +//***************************************************************************** +#define ADC_IM_MASK3 0x00000008 // Sample sequence 3 mask +#define ADC_IM_MASK2 0x00000004 // Sample sequence 2 mask +#define ADC_IM_MASK1 0x00000002 // Sample sequence 1 mask +#define ADC_IM_MASK0 0x00000001 // Sample sequence 0 mask + +//***************************************************************************** +// +// The following define the bit fields in the ADC_ISC register. +// +//***************************************************************************** +#define ADC_ISC_IN3 0x00000008 // Sample sequence 3 interrupt +#define ADC_ISC_IN2 0x00000004 // Sample sequence 2 interrupt +#define ADC_ISC_IN1 0x00000002 // Sample sequence 1 interrupt +#define ADC_ISC_IN0 0x00000001 // Sample sequence 0 interrupt + +//***************************************************************************** +// +// The following define the bit fields in the ADC_OSTAT register. +// +//***************************************************************************** +#define ADC_OSTAT_OV3 0x00000008 // Sample sequence 3 overflow +#define ADC_OSTAT_OV2 0x00000004 // Sample sequence 2 overflow +#define ADC_OSTAT_OV1 0x00000002 // Sample sequence 1 overflow +#define ADC_OSTAT_OV0 0x00000001 // Sample sequence 0 overflow + +//***************************************************************************** +// +// The following define the bit fields in the ADC_EMUX register. +// +//***************************************************************************** +#define ADC_EMUX_EM3_MASK 0x0000F000 // Event mux 3 mask +#define ADC_EMUX_EM3_PROCESSOR 0x00000000 // Processor event +#define ADC_EMUX_EM3_COMP0 0x00001000 // Analog comparator 0 event +#define ADC_EMUX_EM3_COMP1 0x00002000 // Analog comparator 1 event +#define ADC_EMUX_EM3_COMP2 0x00003000 // Analog comparator 2 event +#define ADC_EMUX_EM3_EXTERNAL 0x00004000 // External event +#define ADC_EMUX_EM3_TIMER 0x00005000 // Timer event +#define ADC_EMUX_EM3_PWM0 0x00006000 // PWM0 event +#define ADC_EMUX_EM3_PWM1 0x00007000 // PWM1 event +#define ADC_EMUX_EM3_PWM2 0x00008000 // PWM2 event +#define ADC_EMUX_EM3_ALWAYS 0x0000F000 // Always event +#define ADC_EMUX_EM2_MASK 0x00000F00 // Event mux 2 mask +#define ADC_EMUX_EM2_PROCESSOR 0x00000000 // Processor event +#define ADC_EMUX_EM2_COMP0 0x00000100 // Analog comparator 0 event +#define ADC_EMUX_EM2_COMP1 0x00000200 // Analog comparator 1 event +#define ADC_EMUX_EM2_COMP2 0x00000300 // Analog comparator 2 event +#define ADC_EMUX_EM2_EXTERNAL 0x00000400 // External event +#define ADC_EMUX_EM2_TIMER 0x00000500 // Timer event +#define ADC_EMUX_EM2_PWM0 0x00000600 // PWM0 event +#define ADC_EMUX_EM2_PWM1 0x00000700 // PWM1 event +#define ADC_EMUX_EM2_PWM2 0x00000800 // PWM2 event +#define ADC_EMUX_EM2_ALWAYS 0x00000F00 // Always event +#define ADC_EMUX_EM1_MASK 0x000000F0 // Event mux 1 mask +#define ADC_EMUX_EM1_PROCESSOR 0x00000000 // Processor event +#define ADC_EMUX_EM1_COMP0 0x00000010 // Analog comparator 0 event +#define ADC_EMUX_EM1_COMP1 0x00000020 // Analog comparator 1 event +#define ADC_EMUX_EM1_COMP2 0x00000030 // Analog comparator 2 event +#define ADC_EMUX_EM1_EXTERNAL 0x00000040 // External event +#define ADC_EMUX_EM1_TIMER 0x00000050 // Timer event +#define ADC_EMUX_EM1_PWM0 0x00000060 // PWM0 event +#define ADC_EMUX_EM1_PWM1 0x00000070 // PWM1 event +#define ADC_EMUX_EM1_PWM2 0x00000080 // PWM2 event +#define ADC_EMUX_EM1_ALWAYS 0x000000F0 // Always event +#define ADC_EMUX_EM0_MASK 0x0000000F // Event mux 0 mask +#define ADC_EMUX_EM0_PROCESSOR 0x00000000 // Processor event +#define ADC_EMUX_EM0_COMP0 0x00000001 // Analog comparator 0 event +#define ADC_EMUX_EM0_COMP1 0x00000002 // Analog comparator 1 event +#define ADC_EMUX_EM0_COMP2 0x00000003 // Analog comparator 2 event +#define ADC_EMUX_EM0_EXTERNAL 0x00000004 // External event +#define ADC_EMUX_EM0_TIMER 0x00000005 // Timer event +#define ADC_EMUX_EM0_PWM0 0x00000006 // PWM0 event +#define ADC_EMUX_EM0_PWM1 0x00000007 // PWM1 event +#define ADC_EMUX_EM0_PWM2 0x00000008 // PWM2 event +#define ADC_EMUX_EM0_ALWAYS 0x0000000F // Always event +#define ADC_EMUX_EM0_SHIFT 0 // The shift for the first event +#define ADC_EMUX_EM1_SHIFT 4 // The shift for the second event +#define ADC_EMUX_EM2_SHIFT 8 // The shift for the third event +#define ADC_EMUX_EM3_SHIFT 12 // The shift for the fourth event + +//***************************************************************************** +// +// The following define the bit fields in the ADC_USTAT register. +// +//***************************************************************************** +#define ADC_USTAT_UV3 0x00000008 // Sample sequence 3 underflow +#define ADC_USTAT_UV2 0x00000004 // Sample sequence 2 underflow +#define ADC_USTAT_UV1 0x00000002 // Sample sequence 1 underflow +#define ADC_USTAT_UV0 0x00000001 // Sample sequence 0 underflow + +//***************************************************************************** +// +// The following define the bit fields in the ADC_SSPRI register. +// +//***************************************************************************** +#define ADC_SSPRI_SS3_MASK 0x00003000 // Sequencer 3 priority mask +#define ADC_SSPRI_SS3_1ST 0x00000000 // First priority +#define ADC_SSPRI_SS3_2ND 0x00001000 // Second priority +#define ADC_SSPRI_SS3_3RD 0x00002000 // Third priority +#define ADC_SSPRI_SS3_4TH 0x00003000 // Fourth priority +#define ADC_SSPRI_SS2_MASK 0x00000300 // Sequencer 2 priority mask +#define ADC_SSPRI_SS2_1ST 0x00000000 // First priority +#define ADC_SSPRI_SS2_2ND 0x00000100 // Second priority +#define ADC_SSPRI_SS2_3RD 0x00000200 // Third priority +#define ADC_SSPRI_SS2_4TH 0x00000300 // Fourth priority +#define ADC_SSPRI_SS1_MASK 0x00000030 // Sequencer 1 priority mask +#define ADC_SSPRI_SS1_1ST 0x00000000 // First priority +#define ADC_SSPRI_SS1_2ND 0x00000010 // Second priority +#define ADC_SSPRI_SS1_3RD 0x00000020 // Third priority +#define ADC_SSPRI_SS1_4TH 0x00000030 // Fourth priority +#define ADC_SSPRI_SS0_MASK 0x00000003 // Sequencer 0 priority mask +#define ADC_SSPRI_SS0_1ST 0x00000000 // First priority +#define ADC_SSPRI_SS0_2ND 0x00000001 // Second priority +#define ADC_SSPRI_SS0_3RD 0x00000002 // Third priority +#define ADC_SSPRI_SS0_4TH 0x00000003 // Fourth priority + +//***************************************************************************** +// +// The following define the bit fields in the ADC_PSSI register. +// +//***************************************************************************** +#define ADC_PSSI_SS3 0x00000008 // Trigger sample sequencer 3 +#define ADC_PSSI_SS2 0x00000004 // Trigger sample sequencer 2 +#define ADC_PSSI_SS1 0x00000002 // Trigger sample sequencer 1 +#define ADC_PSSI_SS0 0x00000001 // Trigger sample sequencer 0 + +//***************************************************************************** +// +// The following define the bit fields in the ADC_SAC register. +// +//***************************************************************************** +#define ADC_SAC_AVG_OFF 0x00000000 // No hardware oversampling +#define ADC_SAC_AVG_2X 0x00000001 // 2x hardware oversampling +#define ADC_SAC_AVG_4X 0x00000002 // 4x hardware oversampling +#define ADC_SAC_AVG_8X 0x00000003 // 8x hardware oversampling +#define ADC_SAC_AVG_16X 0x00000004 // 16x hardware oversampling +#define ADC_SAC_AVG_32X 0x00000005 // 32x hardware oversampling +#define ADC_SAC_AVG_64X 0x00000006 // 64x hardware oversampling + +//***************************************************************************** +// +// The following define the bit fields in the ADC_SSMUX0, ADC_SSMUX1, +// ADC_SSMUX2, and ADC_SSMUX3 registers. Not all fields are present in all +// registers. +// +//***************************************************************************** +#define ADC_SSMUX_MUX7_MASK 0x70000000 // 8th mux select mask +#define ADC_SSMUX_MUX6_MASK 0x07000000 // 7th mux select mask +#define ADC_SSMUX_MUX5_MASK 0x00700000 // 6th mux select mask +#define ADC_SSMUX_MUX4_MASK 0x00070000 // 5th mux select mask +#define ADC_SSMUX_MUX3_MASK 0x00007000 // 4th mux select mask +#define ADC_SSMUX_MUX2_MASK 0x00000700 // 3rd mux select mask +#define ADC_SSMUX_MUX1_MASK 0x00000070 // 2nd mux select mask +#define ADC_SSMUX_MUX0_MASK 0x00000007 // 1st mux select mask +#define ADC_SSMUX_MUX7_SHIFT 28 +#define ADC_SSMUX_MUX6_SHIFT 24 +#define ADC_SSMUX_MUX5_SHIFT 20 +#define ADC_SSMUX_MUX4_SHIFT 16 +#define ADC_SSMUX_MUX3_SHIFT 12 +#define ADC_SSMUX_MUX2_SHIFT 8 +#define ADC_SSMUX_MUX1_SHIFT 4 +#define ADC_SSMUX_MUX0_SHIFT 0 + +//***************************************************************************** +// +// The following define the bit fields in the ADC_SSCTL0, ADC_SSCTL1, +// ADC_SSCTL2, and ADC_SSCTL3 registers. Not all fields are present in all +// registers. +// +//***************************************************************************** +#define ADC_SSCTL_TS7 0x80000000 // 8th temperature sensor select +#define ADC_SSCTL_IE7 0x40000000 // 8th interrupt enable +#define ADC_SSCTL_END7 0x20000000 // 8th sequence end select +#define ADC_SSCTL_D7 0x10000000 // 8th differential select +#define ADC_SSCTL_TS6 0x08000000 // 7th temperature sensor select +#define ADC_SSCTL_IE6 0x04000000 // 7th interrupt enable +#define ADC_SSCTL_END6 0x02000000 // 7th sequence end select +#define ADC_SSCTL_D6 0x01000000 // 7th differential select +#define ADC_SSCTL_TS5 0x00800000 // 6th temperature sensor select +#define ADC_SSCTL_IE5 0x00400000 // 6th interrupt enable +#define ADC_SSCTL_END5 0x00200000 // 6th sequence end select +#define ADC_SSCTL_D5 0x00100000 // 6th differential select +#define ADC_SSCTL_TS4 0x00080000 // 5th temperature sensor select +#define ADC_SSCTL_IE4 0x00040000 // 5th interrupt enable +#define ADC_SSCTL_END4 0x00020000 // 5th sequence end select +#define ADC_SSCTL_D4 0x00010000 // 5th differential select +#define ADC_SSCTL_TS3 0x00008000 // 4th temperature sensor select +#define ADC_SSCTL_IE3 0x00004000 // 4th interrupt enable +#define ADC_SSCTL_END3 0x00002000 // 4th sequence end select +#define ADC_SSCTL_D3 0x00001000 // 4th differential select +#define ADC_SSCTL_TS2 0x00000800 // 3rd temperature sensor select +#define ADC_SSCTL_IE2 0x00000400 // 3rd interrupt enable +#define ADC_SSCTL_END2 0x00000200 // 3rd sequence end select +#define ADC_SSCTL_D2 0x00000100 // 3rd differential select +#define ADC_SSCTL_TS1 0x00000080 // 2nd temperature sensor select +#define ADC_SSCTL_IE1 0x00000040 // 2nd interrupt enable +#define ADC_SSCTL_END1 0x00000020 // 2nd sequence end select +#define ADC_SSCTL_D1 0x00000010 // 2nd differential select +#define ADC_SSCTL_TS0 0x00000008 // 1st temperature sensor select +#define ADC_SSCTL_IE0 0x00000004 // 1st interrupt enable +#define ADC_SSCTL_END0 0x00000002 // 1st sequence end select +#define ADC_SSCTL_D0 0x00000001 // 1st differential select + +//***************************************************************************** +// +// The following define the bit fields in the ADC_SSFIFO0, ADC_SSFIFO1, +// ADC_SSFIFO2, and ADC_SSFIFO3 registers. +// +//***************************************************************************** +#define ADC_SSFIFO_DATA_MASK 0x000003FF // Sample data +#define ADC_SSFIFO_DATA_SHIFT 0 + +//***************************************************************************** +// +// The following define the bit fields in the ADC_SSFSTAT0, ADC_SSFSTAT1, +// ADC_SSFSTAT2, and ADC_SSFSTAT3 registers. +// +//***************************************************************************** +#define ADC_SSFSTAT_FULL 0x00001000 // FIFO is full +#define ADC_SSFSTAT_EMPTY 0x00000100 // FIFO is empty +#define ADC_SSFSTAT_HPTR 0x000000F0 // FIFO head pointer +#define ADC_SSFSTAT_TPTR 0x0000000F // FIFO tail pointer + +//***************************************************************************** +// +// The following define the bit fields in the ADC_TMLB register. +// +//***************************************************************************** +#define ADC_TMLB_LB 0x00000001 // Loopback control signals + +//***************************************************************************** +// +// The following define the bit fields in the loopback ADC data. +// +//***************************************************************************** +#define ADC_LB_CNT_MASK 0x000003C0 // Sample counter mask +#define ADC_LB_CONT 0x00000020 // Continuation sample +#define ADC_LB_DIFF 0x00000010 // Differential sample +#define ADC_LB_TS 0x00000008 // Temperature sensor sample +#define ADC_LB_MUX_MASK 0x00000007 // Input channel number mask +#define ADC_LB_CNT_SHIFT 6 // Sample counter shift +#define ADC_LB_MUX_SHIFT 0 // Input channel number shift + +#endif // __HW_ADC_H__ diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/hw_comp.h b/Demo/CORTEX_LM3S811_GCC/hw_include/hw_comp.h new file mode 100644 index 000000000..991b7a083 --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/hw_comp.h @@ -0,0 +1,118 @@ +//***************************************************************************** +// +// hw_comp.h - Macros used when accessing the comparator hardware. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +#ifndef __HW_COMP_H__ +#define __HW_COMP_H__ + +//***************************************************************************** +// +// The following define the offsets of the comparator registers. +// +//***************************************************************************** +#define COMP_O_MIS 0x00000000 // Interrupt status register +#define COMP_O_RIS 0x00000004 // Raw interrupt status register +#define COMP_O_INTEN 0x00000008 // Interrupt enable register +#define COMP_O_REFCTL 0x00000010 // Reference voltage control reg. +#define COMP_O_ACSTAT0 0x00000020 // Comp0 status register +#define COMP_O_ACCTL0 0x00000024 // Comp0 control register +#define COMP_O_ACSTAT1 0x00000040 // Comp1 status register +#define COMP_O_ACCTL1 0x00000044 // Comp1 control register +#define COMP_O_ACSTAT2 0x00000060 // Comp2 status register +#define COMP_O_ACCTL2 0x00000064 // Comp2 control register + +//***************************************************************************** +// +// The following define the bit fields in the COMP_MIS, COMP_RIS, and +// COMP_INTEN registers. +// +//***************************************************************************** +#define COMP_INT_2 0x00000004 // Comp2 interrupt +#define COMP_INT_1 0x00000002 // Comp1 interrupt +#define COMP_INT_0 0x00000001 // Comp0 interrupt + +//***************************************************************************** +// +// The following define the bit fields in the COMP_REFCTL register. +// +//***************************************************************************** +#define COMP_REFCTL_EN 0x00000200 // Reference voltage enable +#define COMP_REFCTL_RNG 0x00000100 // Reference voltage range +#define COMP_REFCTL_VREF_MASK 0x0000000F // Reference voltage select mask +#define COMP_REFCTL_VREF_SHIFT 0 + +//***************************************************************************** +// +// The following define the bit fields in the COMP_ACSTAT0, COMP_ACSTAT1, and +// COMP_ACSTAT2 registers. +// +//***************************************************************************** +#define COMP_ACSTAT_OVAL 0x00000002 // Comparator output value + +//***************************************************************************** +// +// The following define the bit fields in the COMP_ACCTL0, COMP_ACCTL1, and +// COMP_ACCTL2 registers. +// +//***************************************************************************** +#define COMP_ACCTL_TMASK 0x00000800 // Trigger enable +#define COMP_ACCTL_ASRCP_MASK 0x00000600 // Vin+ source select mask +#define COMP_ACCTL_ASRCP_PIN 0x00000000 // Dedicated Comp+ pin +#define COMP_ACCTL_ASRCP_PIN0 0x00000200 // Comp0+ pin +#define COMP_ACCTL_ASRCP_REF 0x00000400 // Internal voltage reference +#define COMP_ACCTL_ASRCP_RES 0x00000600 // Reserved +#define COMP_ACCTL_OEN 0x00000100 // Comparator output enable +#define COMP_ACCTL_TSVAL 0x00000080 // Trigger polarity select +#define COMP_ACCTL_TSEN_MASK 0x00000060 // Trigger sense mask +#define COMP_ACCTL_TSEN_LEVEL 0x00000000 // Trigger is level sense +#define COMP_ACCTL_TSEN_FALL 0x00000020 // Trigger is falling edge +#define COMP_ACCTL_TSEN_RISE 0x00000040 // Trigger is rising edge +#define COMP_ACCTL_TSEN_BOTH 0x00000060 // Trigger is both edges +#define COMP_ACCTL_ISLVAL 0x00000010 // Interrupt polarity select +#define COMP_ACCTL_ISEN_MASK 0x0000000C // Interrupt sense mask +#define COMP_ACCTL_ISEN_LEVEL 0x00000000 // Interrupt is level sense +#define COMP_ACCTL_ISEN_FALL 0x00000004 // Interrupt is falling edge +#define COMP_ACCTL_ISEN_RISE 0x00000008 // Interrupt is rising edge +#define COMP_ACCTL_ISEN_BOTH 0x0000000C // Interrupt is both edges +#define COMP_ACCTL_CINV 0x00000002 // Comparator output invert + +//***************************************************************************** +// +// The following define the reset values for the comparator registers. +// +//***************************************************************************** +#define COMP_RV_MIS 0x00000000 // Interrupt status register +#define COMP_RV_RIS 0x00000000 // Raw interrupt status register +#define COMP_RV_INTEN 0x00000000 // Interrupt enable register +#define COMP_RV_REFCTL 0x00000000 // Reference voltage control reg. +#define COMP_RV_ACSTAT0 0x00000000 // Comp0 status register +#define COMP_RV_ACCTL0 0x00000000 // Comp0 control register +#define COMP_RV_ACSTAT1 0x00000000 // Comp1 status register +#define COMP_RV_ACCTL1 0x00000000 // Comp1 control register +#define COMP_RV_ACSTAT2 0x00000000 // Comp2 status register +#define COMP_RV_ACCTL2 0x00000000 // Comp2 control register + +#endif // __HW_COMP_H__ diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/hw_flash.h b/Demo/CORTEX_LM3S811_GCC/hw_include/hw_flash.h new file mode 100644 index 000000000..53128b436 --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/hw_flash.h @@ -0,0 +1,139 @@ +//***************************************************************************** +// +// hw_flash.h - Macros used when accessing the flash controller. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +#ifndef __HW_FLASH_H__ +#define __HW_FLASH_H__ + +//***************************************************************************** +// +// The following define the offsets of the FLASH registers. +// +//***************************************************************************** +#define FLASH_FMA 0x400FD000 // Memory address register +#define FLASH_FMD 0x400FD004 // Memory data register +#define FLASH_FMC 0x400FD008 // Memory control register +#define FLASH_FCRIS 0x400FD00c // Raw interrupt status register +#define FLASH_FCIM 0x400FD010 // Interrupt mask register +#define FLASH_FCMISC 0x400FD014 // Interrupt status register +#define FLASH_FMPRE 0x400FE130 // FLASH read protect register +#define FLASH_FMPPE 0x400FE134 // FLASH program protect register +#define FLASH_USECRL 0x400FE140 // uSec reload register + +//***************************************************************************** +// +// The following define the bit fields in the FLASH_FMC register. +// +//***************************************************************************** +#define FLASH_FMC_WRKEY_MASK 0xFFFF0000 // FLASH write key mask +#define FLASH_FMC_WRKEY 0xA4420000 // FLASH write key +#define FLASH_FMC_COMT 0x00000008 // Commit user register +#define FLASH_FMC_MERASE 0x00000004 // Mass erase FLASH +#define FLASH_FMC_ERASE 0x00000002 // Erase FLASH page +#define FLASH_FMC_WRITE 0x00000001 // Write FLASH word + +//***************************************************************************** +// +// The following define the bit fields in the FLASH_FCRIS register. +// +//***************************************************************************** +#define FLASH_FCRIS_PROGRAM 0x00000002 // Programming status +#define FLASH_FCRIS_ACCESS 0x00000001 // Invalid access status + +//***************************************************************************** +// +// The following define the bit fields in the FLASH_FCIM register. +// +//***************************************************************************** +#define FLASH_FCIM_PROGRAM 0x00000002 // Programming mask +#define FLASH_FCIM_ACCESS 0x00000001 // Invalid access mask + +//***************************************************************************** +// +// The following define the bit fields in the FLASH_FMIS register. +// +//***************************************************************************** +#define FLASH_FCMISC_PROGRAM 0x00000002 // Programming status +#define FLASH_FCMISC_ACCESS 0x00000001 // Invalid access status + +//***************************************************************************** +// +// The following define the bit fields in the FLASH_FMPRE and FLASH_FMPPE +// registers. +// +//***************************************************************************** +#define FLASH_FMP_BLOCK_31 0x80000000 // Enable for block 31 +#define FLASH_FMP_BLOCK_30 0x40000000 // Enable for block 30 +#define FLASH_FMP_BLOCK_29 0x20000000 // Enable for block 29 +#define FLASH_FMP_BLOCK_28 0x10000000 // Enable for block 28 +#define FLASH_FMP_BLOCK_27 0x08000000 // Enable for block 27 +#define FLASH_FMP_BLOCK_26 0x04000000 // Enable for block 26 +#define FLASH_FMP_BLOCK_25 0x02000000 // Enable for block 25 +#define FLASH_FMP_BLOCK_24 0x01000000 // Enable for block 24 +#define FLASH_FMP_BLOCK_23 0x00800000 // Enable for block 23 +#define FLASH_FMP_BLOCK_22 0x00400000 // Enable for block 22 +#define FLASH_FMP_BLOCK_21 0x00200000 // Enable for block 21 +#define FLASH_FMP_BLOCK_20 0x00100000 // Enable for block 20 +#define FLASH_FMP_BLOCK_19 0x00080000 // Enable for block 19 +#define FLASH_FMP_BLOCK_18 0x00040000 // Enable for block 18 +#define FLASH_FMP_BLOCK_17 0x00020000 // Enable for block 17 +#define FLASH_FMP_BLOCK_16 0x00010000 // Enable for block 16 +#define FLASH_FMP_BLOCK_15 0x00008000 // Enable for block 15 +#define FLASH_FMP_BLOCK_14 0x00004000 // Enable for block 14 +#define FLASH_FMP_BLOCK_13 0x00002000 // Enable for block 13 +#define FLASH_FMP_BLOCK_12 0x00001000 // Enable for block 12 +#define FLASH_FMP_BLOCK_11 0x00000800 // Enable for block 11 +#define FLASH_FMP_BLOCK_10 0x00000400 // Enable for block 10 +#define FLASH_FMP_BLOCK_9 0x00000200 // Enable for block 9 +#define FLASH_FMP_BLOCK_8 0x00000100 // Enable for block 8 +#define FLASH_FMP_BLOCK_7 0x00000080 // Enable for block 7 +#define FLASH_FMP_BLOCK_6 0x00000040 // Enable for block 6 +#define FLASH_FMP_BLOCK_5 0x00000020 // Enable for block 5 +#define FLASH_FMP_BLOCK_4 0x00000010 // Enable for block 4 +#define FLASH_FMP_BLOCK_3 0x00000008 // Enable for block 3 +#define FLASH_FMP_BLOCK_2 0x00000004 // Enable for block 2 +#define FLASH_FMP_BLOCK_1 0x00000002 // Enable for block 1 +#define FLASH_FMP_BLOCK_0 0x00000001 // Enable for block 0 + +//***************************************************************************** +// +// The following define the bit fields in the FLASH_USECRL register. +// +//***************************************************************************** +#define FLASH_USECRL_MASK 0x000000FF // Clock per uSec +#define FLASH_USECRL_SHIFT 0 + +//***************************************************************************** +// +// The erase size is the size of the FLASH block that is erased by an erase +// operation, and the protect size is the size of the FLASH block that is +// protected by each protection register. +// +//***************************************************************************** +#define FLASH_ERASE_SIZE 0x00000400 +#define FLASH_PROTECT_SIZE 0x00000800 + +#endif // __HW_FLASH_H__ diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/hw_gpio.h b/Demo/CORTEX_LM3S811_GCC/hw_include/hw_gpio.h new file mode 100644 index 000000000..bf25d3f5a --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/hw_gpio.h @@ -0,0 +1,103 @@ +//***************************************************************************** +// +// hw_gpio.h - Defines and Macros for GPIO hardware. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +#ifndef __HW_GPIO_H__ +#define __HW_GPIO_H__ + +//***************************************************************************** +// +// GPIO Register Offsets. +// +//***************************************************************************** +#define GPIO_O_DATA 0x00000000 // Data register. +#define GPIO_O_DIR 0x00000400 // Data direction register. +#define GPIO_O_IS 0x00000404 // Interrupt sense register. +#define GPIO_O_IBE 0x00000408 // Interrupt both edges register. +#define GPIO_O_IEV 0x0000040C // Intterupt event register. +#define GPIO_O_IM 0x00000410 // Interrupt mask register. +#define GPIO_O_RIS 0x00000414 // Raw interrupt status register. +#define GPIO_O_MIS 0x00000418 // Masked interrupt status reg. +#define GPIO_O_ICR 0x0000041C // Interrupt clear register. +#define GPIO_O_AFSEL 0x00000420 // Mode control select register. +#define GPIO_O_DR2R 0x00000500 // 2ma drive select register. +#define GPIO_O_DR4R 0x00000504 // 4ma drive select register. +#define GPIO_O_DR8R 0x00000508 // 8ma drive select register. +#define GPIO_O_ODR 0x0000050C // Open drain select register. +#define GPIO_O_PUR 0x00000510 // Pull up select register. +#define GPIO_O_PDR 0x00000514 // Pull down select register. +#define GPIO_O_SLR 0x00000518 // Slew rate control enable reg. +#define GPIO_O_DEN 0x0000051C // Digital input enable register. +#define GPIO_O_PeriphID4 0x00000FD0 // +#define GPIO_O_PeriphID5 0x00000FD4 // +#define GPIO_O_PeriphID6 0x00000FD8 // +#define GPIO_O_PeriphID7 0x00000FDC // +#define GPIO_O_PeriphID0 0x00000FE0 // +#define GPIO_O_PeriphID1 0x00000FE4 // +#define GPIO_O_PeriphID2 0x00000FE8 // +#define GPIO_O_PeriphID3 0x00000FEC // +#define GPIO_O_PCellID0 0x00000FF0 // +#define GPIO_O_PCellID1 0x00000FF4 // +#define GPIO_O_PCellID2 0x00000FF8 // +#define GPIO_O_PCellID3 0x00000FFC // + +//***************************************************************************** +// +// GPIO Register reset values. +// +//***************************************************************************** +#define GPIO_RV_DATA 0x00000000 // Data register reset value. +#define GPIO_RV_DIR 0x00000000 // Data direction reg RV. +#define GPIO_RV_IS 0x00000000 // Interrupt sense reg RV. +#define GPIO_RV_IBE 0x00000000 // Interrupt both edges reg RV. +#define GPIO_RV_IEV 0x00000000 // Intterupt event reg RV. +#define GPIO_RV_IM 0x00000000 // Interrupt mask reg RV. +#define GPIO_RV_RIS 0x00000000 // Raw interrupt status reg RV. +#define GPIO_RV_MIS 0x00000000 // Masked interrupt status reg RV. +#define GPIO_RV_IC 0x00000000 // Interrupt clear reg RV. +#define GPIO_RV_AFSEL 0x00000000 // Mode control select reg RV. +#define GPIO_RV_DR2R 0x000000FF // 2ma drive select reg RV. +#define GPIO_RV_DR4R 0x00000000 // 4ma drive select reg RV. +#define GPIO_RV_DR8R 0x00000000 // 8ma drive select reg RV. +#define GPIO_RV_ODR 0x00000000 // Open drain select reg RV. +#define GPIO_RV_PUR 0x000000FF // Pull up select reg RV. +#define GPIO_RV_PDR 0x00000000 // Pull down select reg RV. +#define GPIO_RV_SLR 0x00000000 // Slew rate control enable reg RV. +#define GPIO_RV_DEN 0x000000FF // Digital input enable reg RV. +#define GPIO_RV_PeriphID4 0x00000000 // +#define GPIO_RV_PeriphID5 0x00000000 // +#define GPIO_RV_PeriphID6 0x00000000 // +#define GPIO_RV_PeriphID7 0x00000000 // +#define GPIO_RV_PeriphID0 0x00000061 // +#define GPIO_RV_PeriphID1 0x00000010 // +#define GPIO_RV_PeriphID2 0x00000004 // +#define GPIO_RV_PeriphID3 0x00000000 // +#define GPIO_RV_PCellID0 0x0000000D // +#define GPIO_RV_PCellID1 0x000000F0 // +#define GPIO_RV_PCellID2 0x00000005 // +#define GPIO_RV_PCellID3 0x000000B1 // + +#endif // __HW_GPIO_H__ diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/hw_i2c.h b/Demo/CORTEX_LM3S811_GCC/hw_include/hw_i2c.h new file mode 100644 index 000000000..2c9f46dab --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/hw_i2c.h @@ -0,0 +1,197 @@ +//***************************************************************************** +// +// hw_i2c.h - Macros used when accessing the I2C master and slave hardware. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +#ifndef __HW_I2C_H__ +#define __HW_I2C_H__ + +//***************************************************************************** +// +// The following defines the offset between the I2C master and slave registers. +// +//***************************************************************************** +#define I2C_O_SLAVE 0x00000800 // Offset from master to slave + +//***************************************************************************** +// +// The following define the offsets of the I2C master registers. +// +//***************************************************************************** +#define I2C_MASTER_O_SA 0x00000000 // Slave address register +#define I2C_MASTER_O_CS 0x00000004 // Control and Status register +#define I2C_MASTER_O_DR 0x00000008 // Data register +#define I2C_MASTER_O_TPR 0x0000000C // Timer period register +#define I2C_MASTER_O_IMR 0x00000010 // Interrupt mask register +#define I2C_MASTER_O_RIS 0x00000014 // Raw interrupt status register +#define I2C_MASTER_O_MIS 0x00000018 // Masked interrupt status reg +#define I2C_MASTER_O_MICR 0x0000001c // Interrupt clear register +#define I2C_MASTER_O_CR 0x00000020 // Configuration register + +//***************************************************************************** +// +// The following define the offsets of the I2C slave registers. +// +//***************************************************************************** +#define I2C_SLAVE_O_OAR 0x00000000 // Own address register +#define I2C_SLAVE_O_CSR 0x00000004 // Control/Status register +#define I2C_SLAVE_O_DR 0x00000008 // Data register +#define I2C_SLAVE_O_IM 0x0000000C // Interrupt mask register +#define I2C_SLAVE_O_RIS 0x00000010 // Raw interrupt status register +#define I2C_SLAVE_O_MIS 0x00000014 // Masked interrupt status reg +#define I2C_SLAVE_O_SICR 0x00000018 // Interrupt clear register + +//***************************************************************************** +// +// The followng define the bit fields in the I2C master slave address register. +// +//***************************************************************************** +#define I2C_MASTER_SA_SA_MASK 0x000000FE // Slave address +#define I2C_MASTER_SA_RS 0x00000001 // Receive/send +#define I2C_MASTER_SA_SA_SHIFT 1 + +//***************************************************************************** +// +// The following define the bit fields in the I2C Master Control and Status +// register. +// +//***************************************************************************** +#define I2C_MASTER_CS_ACK 0x00000008 // Acknowlegde +#define I2C_MASTER_CS_STOP 0x00000004 // Stop +#define I2C_MASTER_CS_START 0x00000002 // Start +#define I2C_MASTER_CS_RUN 0x00000001 // Run +#define I2C_MASTER_CS_BUS_BUSY 0x00000040 // Bus busy +#define I2C_MASTER_CS_IDLE 0x00000020 // Idle +#define I2C_MASTER_CS_ARB_LOST 0x00000010 // Lost arbitration +#define I2C_MASTER_CS_DATA_ACK 0x00000008 // Data byte not acknowledged +#define I2C_MASTER_CS_ADDR_ACK 0x00000004 // Address byte not acknowledged +#define I2C_MASTER_CS_ERROR 0x00000002 // Error occurred +#define I2C_MASTER_CS_BUSY 0x00000001 // Controller is TX/RX data +#define I2C_MASTER_CS_ERR_MASK 0x0000001C + +//***************************************************************************** +// +// The following define values used in determining the contents of the I2C +// Master Timer Period register. +// +//***************************************************************************** +#define I2C_MASTER_TPR_SCL_HP 0x00000004 // SCL high period +#define I2C_MASTER_TPR_SCL_LP 0x00000006 // SCL low period +#define I2C_MASTER_TPR_SCL (I2C_MASTER_TPR_SCL_HP + I2C_MASTER_TPR_SCL_LP) +#define I2C_SCL_STANDARD 100000 // SCL standard frequency +#define I2C_SCL_FAST 400000 // SCL fast frequency + +//***************************************************************************** +// +// The following define the bit fields in the I2C Master Interrupt Mask +// register. +// +//***************************************************************************** +#define I2C_MASTER_IMR_IM 0x00000001 // Master interrupt mask + +//***************************************************************************** +// +// The following define the bit fields in the I2C Master Raw Interrupt Status +// register. +// +//***************************************************************************** +#define I2C_MASTER_RIS_RIS 0x00000001 // Master raw interrupt status + +//***************************************************************************** +// +// The following define the bit fields in the I2C Master Masked Interrupt +// Status register. +// +//***************************************************************************** +#define I2C_MASTER_MIS_MIS 0x00000001 // Master masked interrupt status + +//***************************************************************************** +// +// The following define the bit fields in the I2C Master Interrupt Clear +// register. +// +//***************************************************************************** +#define I2C_MASTER_MICR_IC 0x00000001 // Master interrupt clear + +//***************************************************************************** +// +// The following define the bit fields in the I2C Master Configuration +// register. +// +//***************************************************************************** +#define I2C_MASTER_CR_SFE 0x00000020 // Slave function enable +#define I2C_MASTER_CR_MFE 0x00000010 // Master function enable +#define I2C_MASTER_CR_LPBK 0x00000001 // Loopback enable + +//***************************************************************************** +// +// The following define the bit fields in the I2C Slave Own Address register. +// +//***************************************************************************** +#define I2C_SLAVE_SOAR_OAR_MASK 0x0000007F // Slave address + +//***************************************************************************** +// +// The following define the bit fields in the I2C Slave Control/Status +// register. +// +//***************************************************************************** +#define I2C_SLAVE_CSR_DA 0x00000001 // Enable the device +#define I2C_SLAVE_CSR_TREQ 0x00000002 // Transmit request received +#define I2C_SLAVE_CSR_RREQ 0x00000001 // Receive data from I2C master + +//***************************************************************************** +// +// The following define the bit fields in the I2C Slave Interrupt Mask +// register. +// +//***************************************************************************** +#define I2C_SLAVE_IMR_IM 0x00000001 // Slave interrupt mask + +//***************************************************************************** +// +// The following define the bit fields in the I2C Slave Raw Interrupt Status +// register. +// +//***************************************************************************** +#define I2C_SLAVE_RIS_RIS 0x00000001 // Slave raw interrupt status + +//***************************************************************************** +// +// The following define the bit fields in the I2C Slave Masked Interrupt +// Status register. +// +//***************************************************************************** +#define I2C_SLAVE_MIS_MIS 0x00000001 // Slave masked interrupt status + +//***************************************************************************** +// +// The following define the bit fields in the I2C Slave Interrupt Clear +// register. +// +//***************************************************************************** +#define I2C_SLAVE_SICR_IC 0x00000001 // Slave interrupt clear + +#endif // __HW_I2C_H__ diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/hw_ints.h b/Demo/CORTEX_LM3S811_GCC/hw_include/hw_ints.h new file mode 100644 index 000000000..2204a2c07 --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/hw_ints.h @@ -0,0 +1,97 @@ +//***************************************************************************** +// +// hw_ints.h - Macros that define the interrupt assignment on Stellaris. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +#ifndef __HW_INTS_H__ +#define __HW_INTS_H__ + +//***************************************************************************** +// +// The following define the fault assignments. +// +//***************************************************************************** +#define FAULT_NMI 2 // NMI fault +#define FAULT_HARD 3 // Hard fault +#define FAULT_MPU 4 // MPU fault +#define FAULT_BUS 5 // Bus fault +#define FAULT_USAGE 6 // Usage fault +#define FAULT_SVCALL 11 // SVCall +#define FAULT_DEBUG 12 // Debug monitor +#define FAULT_PENDSV 14 // PendSV +#define FAULT_SYSTICK 15 // System Tick + +//***************************************************************************** +// +// The following define the interrupt assignments. +// +//***************************************************************************** +#define INT_GPIOA 16 // GPIO Port A +#define INT_GPIOB 17 // GPIO Port B +#define INT_GPIOC 18 // GPIO Port C +#define INT_GPIOD 19 // GPIO Port D +#define INT_GPIOE 20 // GPIO Port E +#define INT_UART0 21 // UART0 Rx and Tx +#define INT_UART1 22 // UART1 Rx and Tx +#define INT_SSI 23 // SSI Rx and Tx +#define INT_I2C 24 // I2C Master and Slave +#define INT_PWM_FAULT 25 // PWM Fault +#define INT_PWM0 26 // PWM Generator 0 +#define INT_PWM1 27 // PWM Generator 1 +#define INT_PWM2 28 // PWM Generator 2 +#define INT_QEI 29 // Quadrature Encoder +#define INT_ADC0 30 // ADC Sequence 0 +#define INT_ADC1 31 // ADC Sequence 1 +#define INT_ADC2 32 // ADC Sequence 2 +#define INT_ADC3 33 // ADC Sequence 3 +#define INT_WATCHDOG 34 // Watchdog timer +#define INT_TIMER0A 35 // Timer 0 subtimer A +#define INT_TIMER0B 36 // Timer 0 subtimer B +#define INT_TIMER1A 37 // Timer 1 subtimer A +#define INT_TIMER1B 38 // Timer 1 subtimer B +#define INT_TIMER2A 39 // Timer 2 subtimer A +#define INT_TIMER2B 40 // Timer 2 subtimer B +#define INT_COMP0 41 // Analog Comparator 0 +#define INT_COMP1 42 // Analog Comparator 1 +#define INT_COMP2 43 // Analog Comparator 2 +#define INT_SYSCTL 44 // System Control (PLL, OSC, BO) +#define INT_FLASH 45 // FLASH Control + +//***************************************************************************** +// +// The total number of interrupts. +// +//***************************************************************************** +#define NUM_INTERRUPTS 46 + +//***************************************************************************** +// +// The total number of priority levels. +// +//***************************************************************************** +#define NUM_PRIORITY 8 +#define NUM_PRIORITY_BITS 3 + +#endif // __HW_INTS_H__ diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/hw_memmap.h b/Demo/CORTEX_LM3S811_GCC/hw_include/hw_memmap.h new file mode 100644 index 000000000..2b11f3513 --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/hw_memmap.h @@ -0,0 +1,64 @@ +//***************************************************************************** +// +// hw_memmap.h - Macros defining the memory map of Stellaris. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +#ifndef __HW_MEMMAP_H__ +#define __HW_MEMMAP_H__ + +//***************************************************************************** +// +// The following define the base address of the memories and peripherals. +// +//***************************************************************************** +#define FLASH_BASE 0x00000000 // FLASH memory +#define SRAM_BASE 0x20000000 // SRAM memory +#define WATCHDOG_BASE 0x40000000 // Watchdog +#define GPIO_PORTA_BASE 0x40004000 // GPIO Port A +#define GPIO_PORTB_BASE 0x40005000 // GPIO Port B +#define GPIO_PORTC_BASE 0x40006000 // GPIO Port C +#define GPIO_PORTD_BASE 0x40007000 // GPIO Port D +#define SSI_BASE 0x40008000 // SSI +#define UART0_BASE 0x4000C000 // UART0 +#define UART1_BASE 0x4000D000 // UART1 +#define I2C_MASTER_BASE 0x40020000 // I2C Master +#define I2C_SLAVE_BASE 0x40020800 // I2C Slave +#define GPIO_PORTE_BASE 0x40024000 // GPIO Port E +#define PWM_BASE 0x40028000 // PWM +#define QEI_BASE 0x4002C000 // QEI +#define TIMER0_BASE 0x40030000 // Timer0 +#define TIMER1_BASE 0x40031000 // Timer1 +#define TIMER2_BASE 0x40032000 // Timer2 +#define ADC_BASE 0x40038000 // ADC +#define COMP_BASE 0x4003C000 // Analog comparators +#define FLASH_CTRL_BASE 0x400FD000 // FLASH Controller +#define SYSCTL_BASE 0x400FE000 // System Control +#define ITM_BASE 0xE0000000 // Instrumentation Trace Macrocell +#define DWT_BASE 0xE0001000 // Data Watchpoint and Trace +#define FPB_BASE 0xE0002000 // FLASH Patch and Breakpoint +#define NVIC_BASE 0xE000E000 // Nested Vectored Interrupt Ctrl +#define TPIU_BASE 0xE0040000 // Trace Port Interface Unit + +#endif // __HW_MEMMAP_H__ diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/hw_nvic.h b/Demo/CORTEX_LM3S811_GCC/hw_include/hw_nvic.h new file mode 100644 index 000000000..6598ef88b --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/hw_nvic.h @@ -0,0 +1,830 @@ +//***************************************************************************** +// +// hw_nvic.h - Macros used when accessing the NVIC hardware. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +#ifndef __HW_NVIC_H__ +#define __HW_NVIC_H__ + +//***************************************************************************** +// +// The following define the addresses of the NVIC registers. +// +//***************************************************************************** +#define NVIC_INT_TYPE 0xE000E004 // Interrupt Controller Type Reg. +#define NVIC_ST_CTRL 0xE000E010 // SysTick Control and Status Reg. +#define NVIC_ST_RELOAD 0xE000E014 // SysTick Reload Value Register +#define NVIC_ST_CURRENT 0xE000E018 // SysTick Current Value Register +#define NVIC_ST_CAL 0xE000E01C // SysTick Calibration Value Reg. +#define NVIC_EN0 0xE000E100 // IRQ 0 to 31 Set Enable Register +#define NVIC_DIS0 0xE000E180 // IRQ 0 to 31 Clear Enable Reg. +#define NVIC_PEND0 0xE000E200 // IRQ 0 to 31 Set Pending Register +#define NVIC_UNPEND0 0xE000E280 // IRQ 0 to 31 Clear Pending Reg. +#define NVIC_ACTIVE0 0xE000E300 // IRQ 0 to 31 Active Register +#define NVIC_PRI0 0xE000E400 // IRQ 0 to 3 Priority Register +#define NVIC_PRI1 0xE000E404 // IRQ 4 to 7 Priority Register +#define NVIC_PRI2 0xE000E408 // IRQ 8 to 11 Priority Register +#define NVIC_PRI3 0xE000E40C // IRQ 12 to 15 Priority Register +#define NVIC_PRI4 0xE000E410 // IRQ 16 to 19 Priority Register +#define NVIC_PRI5 0xE000E414 // IRQ 20 to 23 Priority Register +#define NVIC_PRI6 0xE000E418 // IRQ 24 to 27 Priority Register +#define NVIC_PRI7 0xE000E41C // IRQ 28 to 31 Priority Register +#define NVIC_CPUID 0xE000ED00 // CPUID Base Register +#define NVIC_INT_CTRL 0xE000ED04 // Interrupt Control State Register +#define NVIC_VTABLE 0xE000ED08 // Vector Table Offset Register +#define NVIC_APINT 0xE000ED0C // App. Int & Reset Control Reg. +#define NVIC_SYS_CTRL 0xE000ED10 // System Control Register +#define NVIC_CFG_CTRL 0xE000ED14 // Configuration Control Register +#define NVIC_SYS_PRI1 0xE000ED18 // Sys. Handlers 4 to 7 Priority +#define NVIC_SYS_PRI2 0xE000ED1C // Sys. Handlers 8 to 11 Priority +#define NVIC_SYS_PRI3 0xE000ED20 // Sys. Handlers 12 to 15 Priority +#define NVIC_SYS_HND_CTRL 0xE000ED24 // System Handler Control and State +#define NVIC_FAULT_STAT 0xE000ED28 // Configurable Fault Status Reg. +#define NVIC_HFAULT_STAT 0xE000ED2C // Hard Fault Status Register +#define NVIC_DEBUG_STAT 0xE000ED30 // Debug Status Register +#define NVIC_MM_ADDR 0xE000ED34 // Mem Manage Address Register +#define NVIC_FAULT_ADDR 0xE000ED38 // Bus Fault Address Register +#define NVIC_MPU_TYPE 0xE000ED90 // MPU Type Register +#define NVIC_MPU_CTRL 0xE000ED94 // MPU Control Register +#define NVIC_MPU_NUMBER 0xE000ED98 // MPU Region Number Register +#define NVIC_MPU_BASE 0xE000ED9C // MPU Region Base Address Register +#define NVIC_MPU_ATTR 0xE000EDA0 // MPU Region Attribute & Size Reg. +#define NVIC_DBG_CTRL 0xE000EDF0 // Debug Control and Status Reg. +#define NVIC_DBG_XFER 0xE000EDF4 // Debug Core Reg. Transfer Select +#define NVIC_DBG_DATA 0xE000EDF8 // Debug Core Register Data +#define NVIC_DBG_INT 0xE000EDFC // Debug Reset Interrupt Control +#define NVIC_SW_TRIG 0xE000EF00 // Software Trigger Interrupt Reg. + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_INT_TYPE register. +// +//***************************************************************************** +#define NVIC_INT_TYPE_LINES_M 0x0000001F // Number of interrupt lines (x32) +#define NVIC_INT_TYPE_LINES_S 0 + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_ST_CTRL register. +// +//***************************************************************************** +#define NVIC_ST_CTRL_COUNT 0x00010000 // Count flag +#define NVIC_ST_CTRL_CLK_SRC 0x00000004 // Clock Source +#define NVIC_ST_CTRL_INTEN 0x00000002 // Interrupt enable +#define NVIC_ST_CTRL_ENABLE 0x00000001 // Counter mode + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_ST_RELOAD register. +// +//***************************************************************************** +#define NVIC_ST_RELOAD_M 0x00FFFFFF // Counter load value +#define NVIC_ST_RELOAD_S 0 + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_ST_CURRENT register. +// +//***************************************************************************** +#define NVIC_ST_CURRENT_M 0x00FFFFFF // Counter current value +#define NVIC_ST_CURRENT_S 0 + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_ST_CAL register. +// +//***************************************************************************** +#define NVIC_ST_CAL_NOREF 0x80000000 // No reference clock +#define NVIC_ST_CAL_SKEW 0x40000000 // Clock skew +#define NVIC_ST_CAL_ONEMS_M 0x00FFFFFF // 1ms reference value +#define NVIC_ST_CAL_ONEMS_S 0 + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_EN0 register. +// +//***************************************************************************** +#define NVIC_EN0_INT31 0x80000000 // Interrupt 31 enable +#define NVIC_EN0_INT30 0x40000000 // Interrupt 30 enable +#define NVIC_EN0_INT29 0x20000000 // Interrupt 29 enable +#define NVIC_EN0_INT28 0x10000000 // Interrupt 28 enable +#define NVIC_EN0_INT27 0x08000000 // Interrupt 27 enable +#define NVIC_EN0_INT26 0x04000000 // Interrupt 26 enable +#define NVIC_EN0_INT25 0x02000000 // Interrupt 25 enable +#define NVIC_EN0_INT24 0x01000000 // Interrupt 24 enable +#define NVIC_EN0_INT23 0x00800000 // Interrupt 23 enable +#define NVIC_EN0_INT22 0x00400000 // Interrupt 22 enable +#define NVIC_EN0_INT21 0x00200000 // Interrupt 21 enable +#define NVIC_EN0_INT20 0x00100000 // Interrupt 20 enable +#define NVIC_EN0_INT19 0x00080000 // Interrupt 19 enable +#define NVIC_EN0_INT18 0x00040000 // Interrupt 18 enable +#define NVIC_EN0_INT17 0x00020000 // Interrupt 17 enable +#define NVIC_EN0_INT16 0x00010000 // Interrupt 16 enable +#define NVIC_EN0_INT15 0x00008000 // Interrupt 15 enable +#define NVIC_EN0_INT14 0x00004000 // Interrupt 14 enable +#define NVIC_EN0_INT13 0x00002000 // Interrupt 13 enable +#define NVIC_EN0_INT12 0x00001000 // Interrupt 12 enable +#define NVIC_EN0_INT11 0x00000800 // Interrupt 11 enable +#define NVIC_EN0_INT10 0x00000400 // Interrupt 10 enable +#define NVIC_EN0_INT9 0x00000200 // Interrupt 9 enable +#define NVIC_EN0_INT8 0x00000100 // Interrupt 8 enable +#define NVIC_EN0_INT7 0x00000080 // Interrupt 7 enable +#define NVIC_EN0_INT6 0x00000040 // Interrupt 6 enable +#define NVIC_EN0_INT5 0x00000020 // Interrupt 5 enable +#define NVIC_EN0_INT4 0x00000010 // Interrupt 4 enable +#define NVIC_EN0_INT3 0x00000008 // Interrupt 3 enable +#define NVIC_EN0_INT2 0x00000004 // Interrupt 2 enable +#define NVIC_EN0_INT1 0x00000002 // Interrupt 1 enable +#define NVIC_EN0_INT0 0x00000001 // Interrupt 0 enable + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_DIS0 register. +// +//***************************************************************************** +#define NVIC_DIS0_INT31 0x80000000 // Interrupt 31 disable +#define NVIC_DIS0_INT30 0x40000000 // Interrupt 30 disable +#define NVIC_DIS0_INT29 0x20000000 // Interrupt 29 disable +#define NVIC_DIS0_INT28 0x10000000 // Interrupt 28 disable +#define NVIC_DIS0_INT27 0x08000000 // Interrupt 27 disable +#define NVIC_DIS0_INT26 0x04000000 // Interrupt 26 disable +#define NVIC_DIS0_INT25 0x02000000 // Interrupt 25 disable +#define NVIC_DIS0_INT24 0x01000000 // Interrupt 24 disable +#define NVIC_DIS0_INT23 0x00800000 // Interrupt 23 disable +#define NVIC_DIS0_INT22 0x00400000 // Interrupt 22 disable +#define NVIC_DIS0_INT21 0x00200000 // Interrupt 21 disable +#define NVIC_DIS0_INT20 0x00100000 // Interrupt 20 disable +#define NVIC_DIS0_INT19 0x00080000 // Interrupt 19 disable +#define NVIC_DIS0_INT18 0x00040000 // Interrupt 18 disable +#define NVIC_DIS0_INT17 0x00020000 // Interrupt 17 disable +#define NVIC_DIS0_INT16 0x00010000 // Interrupt 16 disable +#define NVIC_DIS0_INT15 0x00008000 // Interrupt 15 disable +#define NVIC_DIS0_INT14 0x00004000 // Interrupt 14 disable +#define NVIC_DIS0_INT13 0x00002000 // Interrupt 13 disable +#define NVIC_DIS0_INT12 0x00001000 // Interrupt 12 disable +#define NVIC_DIS0_INT11 0x00000800 // Interrupt 11 disable +#define NVIC_DIS0_INT10 0x00000400 // Interrupt 10 disable +#define NVIC_DIS0_INT9 0x00000200 // Interrupt 9 disable +#define NVIC_DIS0_INT8 0x00000100 // Interrupt 8 disable +#define NVIC_DIS0_INT7 0x00000080 // Interrupt 7 disable +#define NVIC_DIS0_INT6 0x00000040 // Interrupt 6 disable +#define NVIC_DIS0_INT5 0x00000020 // Interrupt 5 disable +#define NVIC_DIS0_INT4 0x00000010 // Interrupt 4 disable +#define NVIC_DIS0_INT3 0x00000008 // Interrupt 3 disable +#define NVIC_DIS0_INT2 0x00000004 // Interrupt 2 disable +#define NVIC_DIS0_INT1 0x00000002 // Interrupt 1 disable +#define NVIC_DIS0_INT0 0x00000001 // Interrupt 0 disable + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_PEND0 register. +// +//***************************************************************************** +#define NVIC_PEND0_INT31 0x80000000 // Interrupt 31 pend +#define NVIC_PEND0_INT30 0x40000000 // Interrupt 30 pend +#define NVIC_PEND0_INT29 0x20000000 // Interrupt 29 pend +#define NVIC_PEND0_INT28 0x10000000 // Interrupt 28 pend +#define NVIC_PEND0_INT27 0x08000000 // Interrupt 27 pend +#define NVIC_PEND0_INT26 0x04000000 // Interrupt 26 pend +#define NVIC_PEND0_INT25 0x02000000 // Interrupt 25 pend +#define NVIC_PEND0_INT24 0x01000000 // Interrupt 24 pend +#define NVIC_PEND0_INT23 0x00800000 // Interrupt 23 pend +#define NVIC_PEND0_INT22 0x00400000 // Interrupt 22 pend +#define NVIC_PEND0_INT21 0x00200000 // Interrupt 21 pend +#define NVIC_PEND0_INT20 0x00100000 // Interrupt 20 pend +#define NVIC_PEND0_INT19 0x00080000 // Interrupt 19 pend +#define NVIC_PEND0_INT18 0x00040000 // Interrupt 18 pend +#define NVIC_PEND0_INT17 0x00020000 // Interrupt 17 pend +#define NVIC_PEND0_INT16 0x00010000 // Interrupt 16 pend +#define NVIC_PEND0_INT15 0x00008000 // Interrupt 15 pend +#define NVIC_PEND0_INT14 0x00004000 // Interrupt 14 pend +#define NVIC_PEND0_INT13 0x00002000 // Interrupt 13 pend +#define NVIC_PEND0_INT12 0x00001000 // Interrupt 12 pend +#define NVIC_PEND0_INT11 0x00000800 // Interrupt 11 pend +#define NVIC_PEND0_INT10 0x00000400 // Interrupt 10 pend +#define NVIC_PEND0_INT9 0x00000200 // Interrupt 9 pend +#define NVIC_PEND0_INT8 0x00000100 // Interrupt 8 pend +#define NVIC_PEND0_INT7 0x00000080 // Interrupt 7 pend +#define NVIC_PEND0_INT6 0x00000040 // Interrupt 6 pend +#define NVIC_PEND0_INT5 0x00000020 // Interrupt 5 pend +#define NVIC_PEND0_INT4 0x00000010 // Interrupt 4 pend +#define NVIC_PEND0_INT3 0x00000008 // Interrupt 3 pend +#define NVIC_PEND0_INT2 0x00000004 // Interrupt 2 pend +#define NVIC_PEND0_INT1 0x00000002 // Interrupt 1 pend +#define NVIC_PEND0_INT0 0x00000001 // Interrupt 0 pend + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_UNPEND0 register. +// +//***************************************************************************** +#define NVIC_UNPEND0_INT31 0x80000000 // Interrupt 31 unpend +#define NVIC_UNPEND0_INT30 0x40000000 // Interrupt 30 unpend +#define NVIC_UNPEND0_INT29 0x20000000 // Interrupt 29 unpend +#define NVIC_UNPEND0_INT28 0x10000000 // Interrupt 28 unpend +#define NVIC_UNPEND0_INT27 0x08000000 // Interrupt 27 unpend +#define NVIC_UNPEND0_INT26 0x04000000 // Interrupt 26 unpend +#define NVIC_UNPEND0_INT25 0x02000000 // Interrupt 25 unpend +#define NVIC_UNPEND0_INT24 0x01000000 // Interrupt 24 unpend +#define NVIC_UNPEND0_INT23 0x00800000 // Interrupt 23 unpend +#define NVIC_UNPEND0_INT22 0x00400000 // Interrupt 22 unpend +#define NVIC_UNPEND0_INT21 0x00200000 // Interrupt 21 unpend +#define NVIC_UNPEND0_INT20 0x00100000 // Interrupt 20 unpend +#define NVIC_UNPEND0_INT19 0x00080000 // Interrupt 19 unpend +#define NVIC_UNPEND0_INT18 0x00040000 // Interrupt 18 unpend +#define NVIC_UNPEND0_INT17 0x00020000 // Interrupt 17 unpend +#define NVIC_UNPEND0_INT16 0x00010000 // Interrupt 16 unpend +#define NVIC_UNPEND0_INT15 0x00008000 // Interrupt 15 unpend +#define NVIC_UNPEND0_INT14 0x00004000 // Interrupt 14 unpend +#define NVIC_UNPEND0_INT13 0x00002000 // Interrupt 13 unpend +#define NVIC_UNPEND0_INT12 0x00001000 // Interrupt 12 unpend +#define NVIC_UNPEND0_INT11 0x00000800 // Interrupt 11 unpend +#define NVIC_UNPEND0_INT10 0x00000400 // Interrupt 10 unpend +#define NVIC_UNPEND0_INT9 0x00000200 // Interrupt 9 unpend +#define NVIC_UNPEND0_INT8 0x00000100 // Interrupt 8 unpend +#define NVIC_UNPEND0_INT7 0x00000080 // Interrupt 7 unpend +#define NVIC_UNPEND0_INT6 0x00000040 // Interrupt 6 unpend +#define NVIC_UNPEND0_INT5 0x00000020 // Interrupt 5 unpend +#define NVIC_UNPEND0_INT4 0x00000010 // Interrupt 4 unpend +#define NVIC_UNPEND0_INT3 0x00000008 // Interrupt 3 unpend +#define NVIC_UNPEND0_INT2 0x00000004 // Interrupt 2 unpend +#define NVIC_UNPEND0_INT1 0x00000002 // Interrupt 1 unpend +#define NVIC_UNPEND0_INT0 0x00000001 // Interrupt 0 unpend + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_ACTIVE0 register. +// +//***************************************************************************** +#define NVIC_ACTIVE0_INT31 0x80000000 // Interrupt 31 active +#define NVIC_ACTIVE0_INT30 0x40000000 // Interrupt 30 active +#define NVIC_ACTIVE0_INT29 0x20000000 // Interrupt 29 active +#define NVIC_ACTIVE0_INT28 0x10000000 // Interrupt 28 active +#define NVIC_ACTIVE0_INT27 0x08000000 // Interrupt 27 active +#define NVIC_ACTIVE0_INT26 0x04000000 // Interrupt 26 active +#define NVIC_ACTIVE0_INT25 0x02000000 // Interrupt 25 active +#define NVIC_ACTIVE0_INT24 0x01000000 // Interrupt 24 active +#define NVIC_ACTIVE0_INT23 0x00800000 // Interrupt 23 active +#define NVIC_ACTIVE0_INT22 0x00400000 // Interrupt 22 active +#define NVIC_ACTIVE0_INT21 0x00200000 // Interrupt 21 active +#define NVIC_ACTIVE0_INT20 0x00100000 // Interrupt 20 active +#define NVIC_ACTIVE0_INT19 0x00080000 // Interrupt 19 active +#define NVIC_ACTIVE0_INT18 0x00040000 // Interrupt 18 active +#define NVIC_ACTIVE0_INT17 0x00020000 // Interrupt 17 active +#define NVIC_ACTIVE0_INT16 0x00010000 // Interrupt 16 active +#define NVIC_ACTIVE0_INT15 0x00008000 // Interrupt 15 active +#define NVIC_ACTIVE0_INT14 0x00004000 // Interrupt 14 active +#define NVIC_ACTIVE0_INT13 0x00002000 // Interrupt 13 active +#define NVIC_ACTIVE0_INT12 0x00001000 // Interrupt 12 active +#define NVIC_ACTIVE0_INT11 0x00000800 // Interrupt 11 active +#define NVIC_ACTIVE0_INT10 0x00000400 // Interrupt 10 active +#define NVIC_ACTIVE0_INT9 0x00000200 // Interrupt 9 active +#define NVIC_ACTIVE0_INT8 0x00000100 // Interrupt 8 active +#define NVIC_ACTIVE0_INT7 0x00000080 // Interrupt 7 active +#define NVIC_ACTIVE0_INT6 0x00000040 // Interrupt 6 active +#define NVIC_ACTIVE0_INT5 0x00000020 // Interrupt 5 active +#define NVIC_ACTIVE0_INT4 0x00000010 // Interrupt 4 active +#define NVIC_ACTIVE0_INT3 0x00000008 // Interrupt 3 active +#define NVIC_ACTIVE0_INT2 0x00000004 // Interrupt 2 active +#define NVIC_ACTIVE0_INT1 0x00000002 // Interrupt 1 active +#define NVIC_ACTIVE0_INT0 0x00000001 // Interrupt 0 active + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_PRI0 register. +// +//***************************************************************************** +#define NVIC_PRI0_INT3_M 0xFF000000 // Interrupt 3 priority mask +#define NVIC_PRI0_INT2_M 0x00FF0000 // Interrupt 2 priority mask +#define NVIC_PRI0_INT1_M 0x0000FF00 // Interrupt 1 priority mask +#define NVIC_PRI0_INT0_M 0x000000FF // Interrupt 0 priority mask +#define NVIC_PRI0_INT3_S 24 +#define NVIC_PRI0_INT2_S 16 +#define NVIC_PRI0_INT1_S 8 +#define NVIC_PRI0_INT0_S 0 + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_PRI1 register. +// +//***************************************************************************** +#define NVIC_PRI1_INT7_M 0xFF000000 // Interrupt 7 priority mask +#define NVIC_PRI1_INT6_M 0x00FF0000 // Interrupt 6 priority mask +#define NVIC_PRI1_INT5_M 0x0000FF00 // Interrupt 5 priority mask +#define NVIC_PRI1_INT4_M 0x000000FF // Interrupt 4 priority mask +#define NVIC_PRI1_INT7_S 24 +#define NVIC_PRI1_INT6_S 16 +#define NVIC_PRI1_INT5_S 8 +#define NVIC_PRI1_INT4_S 0 + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_PRI2 register. +// +//***************************************************************************** +#define NVIC_PRI2_INT11_M 0xFF000000 // Interrupt 11 priority mask +#define NVIC_PRI2_INT10_M 0x00FF0000 // Interrupt 10 priority mask +#define NVIC_PRI2_INT9_M 0x0000FF00 // Interrupt 9 priority mask +#define NVIC_PRI2_INT8_M 0x000000FF // Interrupt 8 priority mask +#define NVIC_PRI2_INT11_S 24 +#define NVIC_PRI2_INT10_S 16 +#define NVIC_PRI2_INT9_S 8 +#define NVIC_PRI2_INT8_S 0 + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_PRI3 register. +// +//***************************************************************************** +#define NVIC_PRI3_INT15_M 0xFF000000 // Interrupt 15 priority mask +#define NVIC_PRI3_INT14_M 0x00FF0000 // Interrupt 14 priority mask +#define NVIC_PRI3_INT13_M 0x0000FF00 // Interrupt 13 priority mask +#define NVIC_PRI3_INT12_M 0x000000FF // Interrupt 12 priority mask +#define NVIC_PRI3_INT15_S 24 +#define NVIC_PRI3_INT14_S 16 +#define NVIC_PRI3_INT13_S 8 +#define NVIC_PRI3_INT12_S 0 + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_PRI4 register. +// +//***************************************************************************** +#define NVIC_PRI4_INT19_M 0xFF000000 // Interrupt 19 priority mask +#define NVIC_PRI4_INT18_M 0x00FF0000 // Interrupt 18 priority mask +#define NVIC_PRI4_INT17_M 0x0000FF00 // Interrupt 17 priority mask +#define NVIC_PRI4_INT16_M 0x000000FF // Interrupt 16 priority mask +#define NVIC_PRI4_INT19_S 24 +#define NVIC_PRI4_INT18_S 16 +#define NVIC_PRI4_INT17_S 8 +#define NVIC_PRI4_INT16_S 0 + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_PRI5 register. +// +//***************************************************************************** +#define NVIC_PRI5_INT23_M 0xFF000000 // Interrupt 23 priority mask +#define NVIC_PRI5_INT22_M 0x00FF0000 // Interrupt 22 priority mask +#define NVIC_PRI5_INT21_M 0x0000FF00 // Interrupt 21 priority mask +#define NVIC_PRI5_INT20_M 0x000000FF // Interrupt 20 priority mask +#define NVIC_PRI5_INT23_S 24 +#define NVIC_PRI5_INT22_S 16 +#define NVIC_PRI5_INT21_S 8 +#define NVIC_PRI5_INT20_S 0 + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_PRI6 register. +// +//***************************************************************************** +#define NVIC_PRI6_INT27_M 0xFF000000 // Interrupt 27 priority mask +#define NVIC_PRI6_INT26_M 0x00FF0000 // Interrupt 26 priority mask +#define NVIC_PRI6_INT25_M 0x0000FF00 // Interrupt 25 priority mask +#define NVIC_PRI6_INT24_M 0x000000FF // Interrupt 24 priority mask +#define NVIC_PRI6_INT27_S 24 +#define NVIC_PRI6_INT26_S 16 +#define NVIC_PRI6_INT25_S 8 +#define NVIC_PRI6_INT24_S 0 + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_PRI7 register. +// +//***************************************************************************** +#define NVIC_PRI7_INT31_M 0xFF000000 // Interrupt 31 priority mask +#define NVIC_PRI7_INT30_M 0x00FF0000 // Interrupt 30 priority mask +#define NVIC_PRI7_INT29_M 0x0000FF00 // Interrupt 29 priority mask +#define NVIC_PRI7_INT28_M 0x000000FF // Interrupt 28 priority mask +#define NVIC_PRI7_INT31_S 24 +#define NVIC_PRI7_INT30_S 16 +#define NVIC_PRI7_INT29_S 8 +#define NVIC_PRI7_INT28_S 0 + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_CPUID register. +// +//***************************************************************************** +#define NVIC_CPUID_IMP_M 0xFF000000 // Implementer +#define NVIC_CPUID_VAR_M 0x00F00000 // Variant +#define NVIC_CPUID_PARTNO_M 0x0000FFF0 // Processor part number +#define NVIC_CPUID_REV_M 0x0000000F // Revision + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_INT_CTRL register. +// +//***************************************************************************** +#define NVIC_INT_CTRL_NMI_SET 0x80000000 // Pend a NMI +#define NVIC_INT_CTRL_PEND_SV 0x10000000 // Pend a PendSV +#define NVIC_INT_CTRL_UNPEND_SV 0x08000000 // Unpend a PendSV +#define NVIC_INT_CTRL_ISR_PRE 0x00800000 // Debug interrupt handling +#define NVIC_INT_CTRL_ISR_PEND 0x00400000 // Debug interrupt pending +#define NVIC_INT_CTRL_VEC_PEN_M 0x003FF000 // Highest pending exception +#define NVIC_INT_CTRL_RET_BASE 0x00000800 // Return to base +#define NVIC_INT_CTRL_VEC_ACT_M 0x000003FF // Current active exception +#define NVIC_INT_CTRL_VEC_PEN_S 12 +#define NVIC_INT_CTRL_VEC_ACT_S 0 + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_VTABLE register. +// +//***************************************************************************** +#define NVIC_VTABLE_BASE 0x20000000 // Vector table base +#define NVIC_VTABLE_OFFSET_M 0x1FFFFF00 // Vector table offset +#define NVIC_VTABLE_OFFSET_S 8 + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_APINT register. +// +//***************************************************************************** +#define NVIC_APINT_VECTKEY_M 0xFFFF0000 // Vector key mask +#define NVIC_APINT_VECTKEY 0x05FA0000 // Vector key +#define NVIC_APINT_ENDIANESS 0x00008000 // Data endianess +#define NVIC_APINT_PRIGROUP_M 0x00000700 // Priority group +#define NVIC_APINT_PRIGROUP_7_1 0x00000000 // Priority group 7.1 split +#define NVIC_APINT_PRIGROUP_6_2 0x00000100 // Priority group 6.2 split +#define NVIC_APINT_PRIGROUP_5_3 0x00000200 // Priority group 5.3 split +#define NVIC_APINT_PRIGROUP_4_4 0x00000300 // Priority group 4.4 split +#define NVIC_APINT_PRIGROUP_3_5 0x00000400 // Priority group 3.5 split +#define NVIC_APINT_PRIGROUP_2_6 0x00000500 // Priority group 2.6 split +#define NVIC_APINT_PRIGROUP_1_7 0x00000600 // Priority group 1.7 split +#define NVIC_APINT_PRIGROUP_0_8 0x00000700 // Priority group 0.8 split +#define NVIC_APINT_SYSRESETREQ 0x00000004 // System reset request +#define NVIC_APINT_VECT_CLR_ACT 0x00000002 // Clear active NMI/fault info +#define NVIC_APINT_VECT_RESET 0x00000001 // System reset + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_SYS_CTRL register. +// +//***************************************************************************** +#define NVIC_SYS_CTRL_SEVONPEND 0x00000010 // Wakeup on pend +#define NVIC_SYS_CTRL_SLEEPDEEP 0x00000004 // Deep sleep enable +#define NVIC_SYS_CTRL_SLEEPEXIT 0x00000002 // Sleep on ISR exit + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_CFG_CTRL register. +// +//***************************************************************************** +#define NVIC_CFG_CTRL_BFHFNMIGN 0x00000100 // Ignore bus fault in NMI/fault +#define NVIC_CFG_CTRL_DIV0 0x00000010 // Trap on divide by 0 +#define NVIC_CFG_CTRL_UNALIGNED 0x00000008 // Trap on unaligned access +#define NVIC_CFG_CTRL_DEEP_PEND 0x00000004 // Allow deep interrupt trigger +#define NVIC_CFG_CTRL_MAIN_PEND 0x00000002 // Allow main interrupt trigger +#define NVIC_CFG_CTRL_BASE_THR 0x00000001 // Thread state control + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_SYS_PRI1 register. +// +//***************************************************************************** +#define NVIC_SYS_PRI1_RES_M 0xFF000000 // Priority of reserved handler +#define NVIC_SYS_PRI1_USAGE_M 0x00FF0000 // Priority of usage fault handler +#define NVIC_SYS_PRI1_BUS_M 0x0000FF00 // Priority of bus fault handler +#define NVIC_SYS_PRI1_MEM_M 0x000000FF // Priority of mem manage handler +#define NVIC_SYS_PRI1_USAGE_S 16 +#define NVIC_SYS_PRI1_BUS_S 8 +#define NVIC_SYS_PRI1_MEM_S 0 + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_SYS_PRI2 register. +// +//***************************************************************************** +#define NVIC_SYS_PRI2_SVC_M 0xFF000000 // Priority of SVCall handler +#define NVIC_SYS_PRI2_RES_M 0x00FFFFFF // Priority of reserved handlers +#define NVIC_SYS_PRI2_SVC_S 24 + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_SYS_PRI3 register. +// +//***************************************************************************** +#define NVIC_SYS_PRI3_TICK_M 0xFF000000 // Priority of Sys Tick handler +#define NVIC_SYS_PRI3_PENDSV_M 0x00FF0000 // Priority of PendSV handler +#define NVIC_SYS_PRI3_RES_M 0x0000FF00 // Priority of reserved handler +#define NVIC_SYS_PRI3_DEBUG_M 0x000000FF // Priority of debug handler +#define NVIC_SYS_PRI3_TICK_S 24 +#define NVIC_SYS_PRI3_PENDSV_S 16 +#define NVIC_SYS_PRI3_DEBUG_S 0 + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_SYS_HND_CTRL register. +// +//***************************************************************************** +#define NVIC_SYS_HND_CTRL_USAGE 0x00040000 // Usage fault enable +#define NVIC_SYS_HND_CTRL_BUS 0x00020000 // Bus fault enable +#define NVIC_SYS_HND_CTRL_MEM 0x00010000 // Mem manage fault enable +#define NVIC_SYS_HND_CTRL_SVC 0x00008000 // SVCall is pended +#define NVIC_SYS_HND_CTRL_BUSP 0x00004000 // Bus fault is pended +#define NVIC_SYS_HND_CTRL_TICK 0x00000800 // Sys tick is active +#define NVIC_SYS_HND_CTRL_PNDSV 0x00000400 // PendSV is active +#define NVIC_SYS_HND_CTRL_MON 0x00000100 // Monitor is active +#define NVIC_SYS_HND_CTRL_SVCA 0x00000080 // SVCall is active +#define NVIC_SYS_HND_CTRL_USGA 0x00000008 // Usage fault is active +#define NVIC_SYS_HND_CTRL_BUSA 0x00000002 // Bus fault is active +#define NVIC_SYS_HND_CTRL_MEMA 0x00000001 // Mem manage is active + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_FAULT_STAT register. +// +//***************************************************************************** +#define NVIC_FAULT_STAT_DIV0 0x02000000 // Divide by zero fault +#define NVIC_FAULT_STAT_UNALIGN 0x01000000 // Unaligned access fault +#define NVIC_FAULT_STAT_NOCP 0x00080000 // No coprocessor fault +#define NVIC_FAULT_STAT_INVPC 0x00040000 // Invalid PC fault +#define NVIC_FAULT_STAT_INVSTAT 0x00020000 // Invalid state fault +#define NVIC_FAULT_STAT_UNDEF 0x00010000 // Undefined instruction fault +#define NVIC_FAULT_STAT_BFARV 0x00008000 // BFAR is valid +#define NVIC_FAULT_STAT_BSTKE 0x00001000 // Stack bus fault +#define NVIC_FAULT_STAT_BUSTKE 0x00000800 // Unstack bus fault +#define NVIC_FAULT_STAT_IMPRE 0x00000400 // Imprecise data bus error +#define NVIC_FAULT_STAT_PRECISE 0x00000200 // Precise data bus error +#define NVIC_FAULT_STAT_IBUS 0x00000100 // Instruction bus fault +#define NVIC_FAULT_STAT_MMARV 0x00000080 // MMAR is valid +#define NVIC_FAULT_STAT_MSTKE 0x00000010 // Stack access violation +#define NVIC_FAULT_STAT_MUSTKE 0x00000008 // Unstack access violation +#define NVIC_FAULT_STAT_DERR 0x00000002 // Data access violation +#define NVIC_FAULT_STAT_IERR 0x00000001 // Instruction access violation + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_HFAULT_STAT register. +// +//***************************************************************************** +#define NVIC_HFAULT_STAT_DBG 0x80000000 // Debug event +#define NVIC_HFAULT_STAT_FORCED 0x40000000 // Cannot execute fault handler +#define NVIC_HFAULT_STAT_VECT 0x00000002 // Vector table read fault + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_DEBUG_STAT register. +// +//***************************************************************************** +#define NVIC_DEBUG_STAT_EXTRNL 0x00000010 // EDBGRQ asserted +#define NVIC_DEBUG_STAT_VCATCH 0x00000008 // Vector catch +#define NVIC_DEBUG_STAT_DWTTRAP 0x00000004 // DWT match +#define NVIC_DEBUG_STAT_BKPT 0x00000002 // Breakpoint instruction +#define NVIC_DEBUG_STAT_HALTED 0x00000001 // Halt request + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_MM_ADDR register. +// +//***************************************************************************** +#define NVIC_MM_ADDR_M 0xFFFFFFFF // Data fault address +#define NVIC_MM_ADDR_S 0 + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_FAULT_ADDR register. +// +//***************************************************************************** +#define NVIC_FAULT_ADDR_M 0xFFFFFFFF // Data bus fault address +#define NVIC_FAULT_ADDR_S 0 + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_EXC_STACK register. +// +//***************************************************************************** +#define NVIC_EXC_STACK_DEEP 0x00000001 // Exception stack + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_EXC_NUM register. +// +//***************************************************************************** +#define NVIC_EXC_NUM_M 0x000003FF // Exception number +#define NVIC_EXC_NUM_S 0 + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_COPRO register. +// +//***************************************************************************** +#define NVIC_COPRO_15_M 0xC0000000 // Coprocessor 15 access mask +#define NVIC_COPRO_15_DENIED 0x00000000 // Coprocessor 15 access denied +#define NVIC_COPRO_15_PRIV 0x40000000 // Coprocessor 15 privileged addess +#define NVIC_COPRO_15_FULL 0xC0000000 // Coprocessor 15 full access +#define NVIC_COPRO_14_M 0x30000000 // Coprocessor 14 access mask +#define NVIC_COPRO_14_DENIED 0x00000000 // Coprocessor 14 access denied +#define NVIC_COPRO_14_PRIV 0x10000000 // Coprocessor 14 privileged addess +#define NVIC_COPRO_14_FULL 0x30000000 // Coprocessor 14 full access +#define NVIC_COPRO_13_M 0x0C000000 // Coprocessor 13 access mask +#define NVIC_COPRO_13_DENIED 0x00000000 // Coprocessor 13 access denied +#define NVIC_COPRO_13_PRIV 0x04000000 // Coprocessor 13 privileged addess +#define NVIC_COPRO_13_FULL 0x0C000000 // Coprocessor 13 full access +#define NVIC_COPRO_12_M 0x03000000 // Coprocessor 12 access mask +#define NVIC_COPRO_12_DENIED 0x00000000 // Coprocessor 12 access denied +#define NVIC_COPRO_12_PRIV 0x01000000 // Coprocessor 12 privileged addess +#define NVIC_COPRO_12_FULL 0x03000000 // Coprocessor 12 full access +#define NVIC_COPRO_11_M 0x00C00000 // Coprocessor 11 access mask +#define NVIC_COPRO_11_DENIED 0x00000000 // Coprocessor 11 access denied +#define NVIC_COPRO_11_PRIV 0x00400000 // Coprocessor 11 privileged addess +#define NVIC_COPRO_11_FULL 0x00C00000 // Coprocessor 11 full access +#define NVIC_COPRO_10_M 0x00300000 // Coprocessor 10 access mask +#define NVIC_COPRO_10_DENIED 0x00000000 // Coprocessor 10 access denied +#define NVIC_COPRO_10_PRIV 0x00100000 // Coprocessor 10 privileged addess +#define NVIC_COPRO_10_FULL 0x00300000 // Coprocessor 10 full access +#define NVIC_COPRO_9_M 0x000C0000 // Coprocessor 9 access mask +#define NVIC_COPRO_9_DENIED 0x00000000 // Coprocessor 9 access denied +#define NVIC_COPRO_9_PRIV 0x00040000 // Coprocessor 9 privileged addess +#define NVIC_COPRO_9_FULL 0x000C0000 // Coprocessor 9 full access +#define NVIC_COPRO_8_M 0x00030000 // Coprocessor 8 access mask +#define NVIC_COPRO_8_DENIED 0x00000000 // Coprocessor 8 access denied +#define NVIC_COPRO_8_PRIV 0x00010000 // Coprocessor 8 privileged addess +#define NVIC_COPRO_8_FULL 0x00030000 // Coprocessor 8 full access +#define NVIC_COPRO_7_M 0x0000C000 // Coprocessor 7 access mask +#define NVIC_COPRO_7_DENIED 0x00000000 // Coprocessor 7 access denied +#define NVIC_COPRO_7_PRIV 0x00004000 // Coprocessor 7 privileged addess +#define NVIC_COPRO_7_FULL 0x0000C000 // Coprocessor 7 full access +#define NVIC_COPRO_6_M 0x00003000 // Coprocessor 6 access mask +#define NVIC_COPRO_6_DENIED 0x00000000 // Coprocessor 6 access denied +#define NVIC_COPRO_6_PRIV 0x00001000 // Coprocessor 6 privileged addess +#define NVIC_COPRO_6_FULL 0x00003000 // Coprocessor 6 full access +#define NVIC_COPRO_5_M 0x00000C00 // Coprocessor 5 access mask +#define NVIC_COPRO_5_DENIED 0x00000000 // Coprocessor 5 access denied +#define NVIC_COPRO_5_PRIV 0x00000400 // Coprocessor 5 privileged addess +#define NVIC_COPRO_5_FULL 0x00000C00 // Coprocessor 5 full access +#define NVIC_COPRO_4_M 0x00000300 // Coprocessor 4 access mask +#define NVIC_COPRO_4_DENIED 0x00000000 // Coprocessor 4 access denied +#define NVIC_COPRO_4_PRIV 0x00000100 // Coprocessor 4 privileged addess +#define NVIC_COPRO_4_FULL 0x00000300 // Coprocessor 4 full access +#define NVIC_COPRO_3_M 0x000000C0 // Coprocessor 3 access mask +#define NVIC_COPRO_3_DENIED 0x00000000 // Coprocessor 3 access denied +#define NVIC_COPRO_3_PRIV 0x00000040 // Coprocessor 3 privileged addess +#define NVIC_COPRO_3_FULL 0x000000C0 // Coprocessor 3 full access +#define NVIC_COPRO_2_M 0x00000030 // Coprocessor 2 access mask +#define NVIC_COPRO_2_DENIED 0x00000000 // Coprocessor 2 access denied +#define NVIC_COPRO_2_PRIV 0x00000010 // Coprocessor 2 privileged addess +#define NVIC_COPRO_2_FULL 0x00000030 // Coprocessor 2 full access +#define NVIC_COPRO_1_M 0x0000000C // Coprocessor 1 access mask +#define NVIC_COPRO_1_DENIED 0x00000000 // Coprocessor 1 access denied +#define NVIC_COPRO_1_PRIV 0x00000004 // Coprocessor 1 privileged addess +#define NVIC_COPRO_1_FULL 0x0000000C // Coprocessor 1 full access +#define NVIC_COPRO_0_M 0x00000003 // Coprocessor 0 access mask +#define NVIC_COPRO_0_DENIED 0x00000000 // Coprocessor 0 access denied +#define NVIC_COPRO_0_PRIV 0x00000001 // Coprocessor 0 privileged addess +#define NVIC_COPRO_0_FULL 0x00000003 // Coprocessor 0 full access + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_MPU_TYPE register. +// +//***************************************************************************** +#define NVIC_MPU_TYPE_IREGION_M 0x00FF0000 // Number of I regions +#define NVIC_MPU_TYPE_DREGION_M 0x0000FF00 // Number of D regions +#define NVIC_MPU_TYPE_SEPARATE 0x00000001 // Separate or unified MPU +#define NVIC_MPU_TYPE_IREGION_S 16 +#define NVIC_MPU_TYPE_DREGION_S 8 + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_MPU_CTRL register. +// +//***************************************************************************** +#define NVIC_MPU_CTRL_HFNMIENA 0x00000002 // MPU enabled during faults +#define NVIC_MPU_CTRL_ENABLE 0x00000001 // MPU enable + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_MPU_NUMBER register. +// +//***************************************************************************** +#define NVIC_MPU_NUMBER_M 0x000000FF // MPU region to access +#define NVIC_MPU_NUMBER_S 0 + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_MPU_BASE register. +// +//***************************************************************************** +#define NVIC_MPU_BASE_ADDR_M 0xFFFFFF00 // Base address +#define NVIC_MPU_BASE_VALID 0x00000010 // Region number valid +#define NVIC_MPU_BASE_REGION_M 0x0000000F // Region number +#define NVIC_MPU_BASE_ADDR_S 8 +#define NVIC_MPU_BASE_REGION_S 0 + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_MPU_ATTR register. +// +//***************************************************************************** +#define NVIC_MPU_ATTR_ATTRS 0xFFFF0000 // Attributes +#define NVIC_MPU_ATTR_SRD 0x0000FF00 // Sub-region disable +#define NVIC_MPU_ATTR_SZENABLE 0x000000FF // Region size + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_DBG_CTRL register. +// +//***************************************************************************** +#define NVIC_DBG_CTRL_DBGKEY_M 0xFFFF0000 // Debug key mask +#define NVIC_DBG_CTRL_DBGKEY 0xA05F0000 // Debug key +#define NVIC_DBG_CTRL_MON_PEND 0x00008000 // Pend the monitor +#define NVIC_DBG_CTRL_MON_REQ 0x00004000 // Monitor request +#define NVIC_DBG_CTRL_MON_EN 0x00002000 // Debug monitor enable +#define NVIC_DBG_CTRL_MONSTEP 0x00001000 // Monitor step the core +#define NVIC_DBG_CTRL_S_SLEEP 0x00000400 // Core is sleeping +#define NVIC_DBG_CTRL_S_HALT 0x00000200 // Core status on halt +#define NVIC_DBG_CTRL_S_REGRDY 0x00000100 // Register read/write available +#define NVIC_DBG_CTRL_S_LOCKUP 0x00000080 // Core is locked up +#define NVIC_DBG_CTRL_C_RESET 0x00000010 // Reset the core +#define NVIC_DBG_CTRL_C_MASKINT 0x00000008 // Mask interrupts when stepping +#define NVIC_DBG_CTRL_C_STEP 0x00000004 // Step the core +#define NVIC_DBG_CTRL_C_HALT 0x00000002 // Halt the core +#define NVIC_DBG_CTRL_C_DEBUGEN 0x00000001 // Enable debug + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_DBG_XFER register. +// +//***************************************************************************** +#define NVIC_DBG_XFER_REG_WNR 0x00010000 // Write or not read +#define NVIC_DBG_XFER_REG_SEL_M 0x0000001F // Register +#define NVIC_DBG_XFER_REG_R0 0x00000000 // Register R0 +#define NVIC_DBG_XFER_REG_R1 0x00000001 // Register R1 +#define NVIC_DBG_XFER_REG_R2 0x00000002 // Register R2 +#define NVIC_DBG_XFER_REG_R3 0x00000003 // Register R3 +#define NVIC_DBG_XFER_REG_R4 0x00000004 // Register R4 +#define NVIC_DBG_XFER_REG_R5 0x00000005 // Register R5 +#define NVIC_DBG_XFER_REG_R6 0x00000006 // Register R6 +#define NVIC_DBG_XFER_REG_R7 0x00000007 // Register R7 +#define NVIC_DBG_XFER_REG_R8 0x00000008 // Register R8 +#define NVIC_DBG_XFER_REG_R9 0x00000009 // Register R9 +#define NVIC_DBG_XFER_REG_R10 0x0000000A // Register R10 +#define NVIC_DBG_XFER_REG_R11 0x0000000B // Register R11 +#define NVIC_DBG_XFER_REG_R12 0x0000000C // Register R12 +#define NVIC_DBG_XFER_REG_R13 0x0000000D // Register R13 +#define NVIC_DBG_XFER_REG_R14 0x0000000E // Register R14 +#define NVIC_DBG_XFER_REG_R15 0x0000000F // Register R15 +#define NVIC_DBG_XFER_REG_FLAGS 0x00000010 // xPSR/Flags register +#define NVIC_DBG_XFER_REG_MSP 0x00000011 // Main SP +#define NVIC_DBG_XFER_REG_PSP 0x00000012 // Process SP +#define NVIC_DBG_XFER_REG_DSP 0x00000013 // Deep SP +#define NVIC_DBG_XFER_REG_CFBP 0x00000014 // Control/Fault/BasePri/PriMask + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_DBG_DATA register. +// +//***************************************************************************** +#define NVIC_DBG_DATA_M 0xFFFFFFFF // Data temporary cache +#define NVIC_DBG_DATA_S 0 + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_DBG_INT register. +// +//***************************************************************************** +#define NVIC_DBG_INT_HARDERR 0x00000400 // Debug trap on hard fault +#define NVIC_DBG_INT_INTERR 0x00000200 // Debug trap on interrupt errors +#define NVIC_DBG_INT_BUSERR 0x00000100 // Debug trap on bus error +#define NVIC_DBG_INT_STATERR 0x00000080 // Debug trap on usage fault state +#define NVIC_DBG_INT_CHKERR 0x00000040 // Debug trap on usage fault check +#define NVIC_DBG_INT_NOCPERR 0x00000020 // Debug trap on coprocessor error +#define NVIC_DBG_INT_MMERR 0x00000010 // Debug trap on mem manage fault +#define NVIC_DBG_INT_RESET 0x00000008 // Core reset status +#define NVIC_DBG_INT_RSTPENDCLR 0x00000004 // Clear pending core reset +#define NVIC_DBG_INT_RSTPENDING 0x00000002 // Core reset is pending +#define NVIC_DBG_INT_RSTVCATCH 0x00000001 // Reset vector catch + +//***************************************************************************** +// +// The following define the bit fields in the NVIC_SW_TRIG register. +// +//***************************************************************************** +#define NVIC_SW_TRIG_INTID_M 0x000003FF // Interrupt to trigger +#define NVIC_SW_TRIG_INTID_S 0 + +#endif // __HW_NVIC_H__ diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/hw_pwm.h b/Demo/CORTEX_LM3S811_GCC/hw_include/hw_pwm.h new file mode 100644 index 000000000..cc42015ab --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/hw_pwm.h @@ -0,0 +1,260 @@ +//***************************************************************************** +// +// hw_pwm.h - Defines and Macros for Pulse Width Modulation (PWM) ports +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +#ifndef __HW_PWM_H__ +#define __HW_PWM_H__ + +//***************************************************************************** +// +// PWM Module Register Offsets. +// +//***************************************************************************** +#define PWM_O_CTL 0x00000000 // PWM Master Control register +#define PWM_O_SYNC 0x00000004 // PWM Time Base Sync register +#define PWM_O_ENABLE 0x00000008 // PWM Output Enable register +#define PWM_O_INVERT 0x0000000C // PWM Output Inversion register +#define PWM_O_FAULT 0x00000010 // PWM Output Fault register +#define PWM_O_INTEN 0x00000014 // PWM Interrupt Enable register +#define PWM_O_RIS 0x00000018 // PWM Interrupt Raw Status reg. +#define PWM_O_ISC 0x0000001C // PWM Interrupt Status register +#define PWM_O_STATUS 0x00000020 // PWM Status register + +//***************************************************************************** +// +// The following define the bit fields in the PWM Master Control register. +// +//***************************************************************************** +#define PWM_CTL_GLOBAL_SYNC2 0x00000004 // Global sync generator 2 +#define PWM_CTL_GLOBAL_SYNC1 0x00000002 // Global sync generator 1 +#define PWM_CTL_GLOBAL_SYNC0 0x00000001 // Global sync generator 0 + +//***************************************************************************** +// +// The following define the bit fields in the PWM Time Base Sync register. +// +//***************************************************************************** +#define PWM_SYNC_SYNC2 0x00000004 // Reset generator 2 counter +#define PWM_SYNC_SYNC1 0x00000002 // Reset generator 1 counter +#define PWM_SYNC_SYNC0 0x00000001 // Reset generator 0 counter + +//***************************************************************************** +// +// The following define the bit fields in the PWM Output Enable register. +// +//***************************************************************************** +#define PWM_ENABLE_PWM5EN 0x00000020 // PWM5 pin enable +#define PWM_ENABLE_PWM4EN 0x00000010 // PWM4 pin enable +#define PWM_ENABLE_PWM3EN 0x00000008 // PWM3 pin enable +#define PWM_ENABLE_PWM2EN 0x00000004 // PWM2 pin enable +#define PWM_ENABLE_PWM1EN 0x00000002 // PWM1 pin enable +#define PWM_ENABLE_PWM0EN 0x00000001 // PWM0 pin enable + +//***************************************************************************** +// +// The following define the bit fields in the PWM Inversion register. +// +//***************************************************************************** +#define PWM_INVERT_PWM5INV 0x00000020 // PWM5 pin invert +#define PWM_INVERT_PWM4INV 0x00000010 // PWM4 pin invert +#define PWM_INVERT_PWM3INV 0x00000008 // PWM3 pin invert +#define PWM_INVERT_PWM2INV 0x00000004 // PWM2 pin invert +#define PWM_INVERT_PWM1INV 0x00000002 // PWM1 pin invert +#define PWM_INVERT_PWM0INV 0x00000001 // PWM0 pin invert + +//***************************************************************************** +// +// The following define the bit fields in the PWM Fault register. +// +//***************************************************************************** +#define PWM_FAULT_FAULT5 0x00000020 // PWM5 pin fault +#define PWM_FAULT_FAULT4 0x00000010 // PWM5 pin fault +#define PWM_FAULT_FAULT3 0x00000008 // PWM5 pin fault +#define PWM_FAULT_FAULT2 0x00000004 // PWM5 pin fault +#define PWM_FAULT_FAULT1 0x00000002 // PWM5 pin fault +#define PWM_FAULT_FAULT0 0x00000001 // PWM5 pin fault + +//***************************************************************************** +// +// PWM Interrupt Register bit definitions. +// +//***************************************************************************** +#define PWM_INT_INTFAULT 0x00010000 // Fault interrupt pending + +//***************************************************************************** +// +// The following define the bit fields in the PWM Status register. +// +//***************************************************************************** +#define PWM_STATUS_FAULT 0x00000001 // Fault status + +//***************************************************************************** +// +// PWM Generator standard offsets. +// +//***************************************************************************** +#define PWM_GEN_0_OFFSET 0x00000040 // PWM0 base +#define PWM_GEN_1_OFFSET 0x00000080 // PWM1 base +#define PWM_GEN_2_OFFSET 0x000000C0 // PWM2 base + +#define PWM_O_X_CTL 0x00000000 // Gen Control Reg +#define PWM_O_X_INTEN 0x00000004 // Gen Int/Trig Enable Reg +#define PWM_O_X_RIS 0x00000008 // Gen Raw Int Status Reg +#define PWM_O_X_ISC 0x0000000C // Gen Int Status Reg +#define PWM_O_X_LOAD 0x00000010 // Gen Load Reg +#define PWM_O_X_COUNT 0x00000014 // Gen Counter Reg +#define PWM_O_X_CMPA 0x00000018 // Gen Compare A Reg +#define PWM_O_X_CMPB 0x0000001C // Gen Compare B Reg +#define PWM_O_X_GENA 0x00000020 // Gen Generator A Ctrl Reg +#define PWM_O_X_GENB 0x00000024 // Gen Generator B Ctrl Reg +#define PWM_O_X_DBCTL 0x00000028 // Gen Dead Band Ctrl Reg +#define PWM_O_X_DBRISE 0x0000002C // Gen DB Rising Edge Delay Reg +#define PWM_O_X_DBFALL 0x00000030 // Gen DB Falling Edge Delay Reg + +//***************************************************************************** +// +// PWM_X Control Register bit definitions. +// +//***************************************************************************** +#define PWM_X_CTL_ENABLE 0x00000001 // Master enable for gen block +#define PWM_X_CTL_MODE 0x00000002 // Counter mode, down or up/down +#define PWM_X_CTL_DEBUG 0x00000004 // Debug mode +#define PWM_X_CTL_LOADUPD 0x00000008 // Update mode for the load reg +#define PWM_X_CTL_CMPAUPD 0x00000010 // Update mode for comp A reg +#define PWM_X_CTL_CMPBUPD 0x00000020 // Update mode for comp B reg + +//***************************************************************************** +// +// PWM_X Interrupt/Trigger Enable Register bit definitions. +// +//***************************************************************************** +#define PWM_X_INTEN_INTCNTZERO 0x00000001 // Int if COUNT = 0 +#define PWM_X_INTEN_INTCNTLOAD 0x00000002 // Int if COUNT = LOAD +#define PWM_X_INTEN_INTCMPAU 0x00000004 // Int if COUNT = CMPA U +#define PWM_X_INTEN_INTCMPAD 0x00000008 // Int if COUNT = CMPA D +#define PWM_X_INTEN_INTCMPBU 0x00000010 // Int if COUNT = CMPA U +#define PWM_X_INTEN_INTCMPBD 0x00000020 // Int if COUNT = CMPA D +#define PWM_X_INTEN_TRCNTZERO 0x00000100 // Trig if COUNT = 0 +#define PWM_X_INTEN_TRCNTLOAD 0x00000200 // Trig if COUNT = LOAD +#define PWM_X_INTEN_TRCMPAU 0x00000400 // Trig if COUNT = CMPA U +#define PWM_X_INTEN_TRCMPAD 0x00000800 // Trig if COUNT = CMPA D +#define PWM_X_INTEN_TRCMPBU 0x00001000 // Trig if COUNT = CMPA U +#define PWM_X_INTEN_TRCMPBD 0x00002000 // Trig if COUNT = CMPA D + +//***************************************************************************** +// +// PWM_X Raw Interrupt Status Register bit definitions. +// +//***************************************************************************** +#define PWM_X_RIS_INTCNTZERO 0x00000001 // PWM_X_COUNT = 0 int +#define PWM_X_RIS_INTCNTLOAD 0x00000002 // PWM_X_COUNT = PWM_X_LOAD int +#define PWM_X_RIS_INTCMPAU 0x00000004 // PWM_X_COUNT = PWM_X_CMPA U int +#define PWM_X_RIS_INTCMPAD 0x00000008 // PWM_X_COUNT = PWM_X_CMPA D int +#define PWM_X_RIS_INTCMPBU 0x00000010 // PWM_X_COUNT = PWM_X_CMPB U int +#define PWM_X_RIS_INTCMPBD 0x00000020 // PWM_X_COUNT = PWM_X_CMPB D int + +//***************************************************************************** +// +// PWM_X Interrupt Status Register bit definitions. +// +//***************************************************************************** +#define PWM_X_INT_INTCNTZERO 0x00000001 // PWM_X_COUNT = 0 received +#define PWM_X_INT_INTCNTLOAD 0x00000002 // PWM_X_COUNT = PWM_X_LOAD rcvd +#define PWM_X_INT_INTCMPAU 0x00000004 // PWM_X_COUNT = PWM_X_CMPA U rcvd +#define PWM_X_INT_INTCMPAD 0x00000008 // PWM_X_COUNT = PWM_X_CMPA D rcvd +#define PWM_X_INT_INTCMPBU 0x00000010 // PWM_X_COUNT = PWM_X_CMPB U rcvd +#define PWM_X_INT_INTCMPBD 0x00000020 // PWM_X_COUNT = PWM_X_CMPB D rcvd + +//***************************************************************************** +// +// PWM_X Generator A/B Control Register bit definitions. +// +//***************************************************************************** +#define PWM_X_GEN_Y_ACTZERO 0x00000003 // Act PWM_X_COUNT = 0 +#define PWM_X_GEN_Y_ACTLOAD 0x0000000C // Act PWM_X_COUNT = PWM_X_LOAD +#define PWM_X_GEN_Y_ACTCMPAU 0x00000030 // Act PWM_X_COUNT = PWM_X_CMPA U +#define PWM_X_GEN_Y_ACTCMPAD 0x000000C0 // Act PWM_X_COUNT = PWM_X_CMPA D +#define PWM_X_GEN_Y_ACTCMPBU 0x00000300 // Act PWM_X_COUNT = PWM_X_CMPB U +#define PWM_X_GEN_Y_ACTCMPBD 0x00000C00 // Act PWM_X_COUNT = PWM_X_CMPB D + +//***************************************************************************** +// +// PWM_X Generator A/B Control Register action definitions. +// +//***************************************************************************** +#define PWM_GEN_ACT_NONE 0x0 // Do nothing +#define PWM_GEN_ACT_INV 0x1 // Invert the output signal +#define PWM_GEN_ACT_ZERO 0x2 // Set the output signal to zero +#define PWM_GEN_ACT_ONE 0x3 // Set the output signal to one +#define PWM_GEN_ACT_ZERO_SHIFT 0 // Shift amount for the zero action +#define PWM_GEN_ACT_LOAD_SHIFT 2 // Shift amount for the load action +#define PWM_GEN_ACT_A_UP_SHIFT 4 // Shift amount for the A up action +#define PWM_GEN_ACT_A_DN_SHIFT 6 // Shift amount for the A dn action +#define PWM_GEN_ACT_B_UP_SHIFT 8 // Shift amount for the B up action +#define PWM_GEN_ACT_B_DN_SHIFT 10 // Shift amount for the B dn action + +//***************************************************************************** +// +// PWM_X Dead Band Control Register bit definitions. +// +//***************************************************************************** +#define PWM_DBCTL_ENABLE 0x00000001 // Enable dead band insertion + +//***************************************************************************** +// +// PWM Register reset values. +// +//***************************************************************************** +#define PWM_RV_CTL 0x00000000 // Master control of the PWM module +#define PWM_RV_SYNC 0x00000000 // Counter synch for PWM generators +#define PWM_RV_ENABLE 0x00000000 // Master enable for the PWM + // output pins +#define PWM_RV_INVERT 0x00000000 // Inversion control for + // PWM output pins +#define PWM_RV_FAULT 0x00000000 // Fault handling for the PWM + // output pins +#define PWM_RV_INTEN 0x00000000 // Interrupt enable +#define PWM_RV_RIS 0x00000000 // Raw interrupt status +#define PWM_RV_ISC 0x00000000 // Interrupt status and clearing +#define PWM_RV_STATUS 0x00000000 // Status +#define PWM_RV_X_CTL 0x00000000 // Master control of the PWM + // generator block +#define PWM_RV_X_INTEN 0x00000000 // Interrupt and trigger enable +#define PWM_RV_X_RIS 0x00000000 // Raw interrupt status +#define PWM_RV_X_ISC 0x00000000 // Interrupt status and clearing +#define PWM_RV_X_LOAD 0x00000000 // The load value for the counter +#define PWM_RV_X_COUNT 0x00000000 // The current counter value +#define PWM_RV_X_CMPA 0x00000000 // The comparator A value +#define PWM_RV_X_CMPB 0x00000000 // The comparator B value +#define PWM_RV_X_GENA 0x00000000 // Controls PWM generator A +#define PWM_RV_X_GENB 0x00000000 // Controls PWM generator B +#define PWM_RV_X_DBCTL 0x00000000 // Control the dead band generator +#define PWM_RV_X_DBRISE 0x00000000 // The dead band rising edge delay + // count +#define PWM_RV_X_DBFALL 0x00000000 // The dead band falling edge delay + // count + +#endif // __HW_PWM_H__ diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/hw_qei.h b/Demo/CORTEX_LM3S811_GCC/hw_include/hw_qei.h new file mode 100644 index 000000000..864459f48 --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/hw_qei.h @@ -0,0 +1,176 @@ +//***************************************************************************** +// +// hw_qei.h - Macros used when accessing the QEI hardware. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +#ifndef __HW_QEI_H__ +#define __HW_QEI_H__ + +//***************************************************************************** +// +// The following define the offsets of the QEI registers. +// +//***************************************************************************** +#define QEI_O_CTL 0x00000000 // Configuration and control reg. +#define QEI_O_STAT 0x00000004 // Status register +#define QEI_O_POS 0x00000008 // Current position register +#define QEI_O_MAXPOS 0x0000000C // Maximum position register +#define QEI_O_LOAD 0x00000010 // Velocity timer load register +#define QEI_O_TIME 0x00000014 // Velocity timer register +#define QEI_O_COUNT 0x00000018 // Velocity pulse count register +#define QEI_O_SPEED 0x0000001C // Velocity speed register +#define QEI_O_INTEN 0x00000020 // Interrupt enable register +#define QEI_O_RIS 0x00000024 // Raw interrupt status register +#define QEI_O_ISC 0x00000028 // Interrupt status register + +//***************************************************************************** +// +// The following define the bit fields in the QEI_CTL register. +// +//***************************************************************************** +#define QEI_CTL_STALLEN 0x00001000 // Stall enable +#define QEI_CTL_INVI 0x00000800 // Invert Index input +#define QEI_CTL_INVB 0x00000400 // Invert PhB input +#define QEI_CTL_INVA 0x00000200 // Invert PhA input +#define QEI_CTL_VELDIV_M 0x000001C0 // Velocity predivider mask +#define QEI_CTL_VELDIV_1 0x00000000 // Predivide by 1 +#define QEI_CTL_VELDIV_2 0x00000040 // Predivide by 2 +#define QEI_CTL_VELDIV_4 0x00000080 // Predivide by 4 +#define QEI_CTL_VELDIV_8 0x000000C0 // Predivide by 8 +#define QEI_CTL_VELDIV_16 0x00000100 // Predivide by 16 +#define QEI_CTL_VELDIV_32 0x00000140 // Predivide by 32 +#define QEI_CTL_VELDIV_64 0x00000180 // Predivide by 64 +#define QEI_CTL_VELDIV_128 0x000001C0 // Predivide by 128 +#define QEI_CTL_VELEN 0x00000020 // Velocity enable +#define QEI_CTL_RESMODE 0x00000010 // Position counter reset mode +#define QEI_CTL_CAPMODE 0x00000008 // Edge capture mode +#define QEI_CTL_SIGMODE 0x00000004 // Encoder signaling mode +#define QEI_CTL_SWAP 0x00000002 // Swap input signals +#define QEI_CTL_ENABLE 0x00000001 // QEI enable + +//***************************************************************************** +// +// The following define the bit fields in the QEI_STAT register. +// +//***************************************************************************** +#define QEI_STAT_DIRECTION 0x00000002 // Direction of rotation +#define QEI_STAT_ERROR 0x00000001 // Signalling error detected + +//***************************************************************************** +// +// The following define the bit fields in the QEI_POS register. +// +//***************************************************************************** +#define QEI_POS_M 0xFFFFFFFF // Current encoder position +#define QEI_POS_S 0 + +//***************************************************************************** +// +// The following define the bit fields in the QEI_MAXPOS register. +// +//***************************************************************************** +#define QEI_MAXPOS_M 0xFFFFFFFF // Maximum encoder position +#define QEI_MAXPOS_S 0 + +//***************************************************************************** +// +// The following define the bit fields in the QEI_LOAD register. +// +//***************************************************************************** +#define QEI_LOAD_M 0xFFFFFFFF // Velocity timer load value +#define QEI_LOAD_S 0 + +//***************************************************************************** +// +// The following define the bit fields in the QEI_TIME register. +// +//***************************************************************************** +#define QEI_TIME_M 0xFFFFFFFF // Velocity timer current value +#define QEI_TIME_S 0 + +//***************************************************************************** +// +// The following define the bit fields in the QEI_COUNT register. +// +//***************************************************************************** +#define QEI_COUNT_M 0xFFFFFFFF // Encoder running pulse count +#define QEI_COUNT_S 0 + +//***************************************************************************** +// +// The following define the bit fields in the QEI_SPEED register. +// +//***************************************************************************** +#define QEI_SPEED_M 0xFFFFFFFF // Encoder pulse count +#define QEI_SPEED_S 0 + +//***************************************************************************** +// +// The following define the bit fields in the QEI_INTEN register. +// +//***************************************************************************** +#define QEI_INTEN_ERROR 0x00000008 // Phase error detected +#define QEI_INTEN_DIR 0x00000004 // Direction change +#define QEI_INTEN_TIMER 0x00000002 // Velocity timer expired +#define QEI_INTEN_INDEX 0x00000001 // Index pulse detected + +//***************************************************************************** +// +// The following define the bit fields in the QEI_RIS register. +// +//***************************************************************************** +#define QEI_RIS_ERROR 0x00000008 // Phase error detected +#define QEI_RIS_DIR 0x00000004 // Direction change +#define QEI_RIS_TIMER 0x00000002 // Velocity timer expired +#define QEI_RIS_INDEX 0x00000001 // Index pulse detected + +//***************************************************************************** +// +// The following define the bit fields in the QEI_ISC register. +// +//***************************************************************************** +#define QEI_INT_ERROR 0x00000008 // Phase error detected +#define QEI_INT_DIR 0x00000004 // Direction change +#define QEI_INT_TIMER 0x00000002 // Velocity timer expired +#define QEI_INT_INDEX 0x00000001 // Index pulse detected + +//***************************************************************************** +// +// The following define the reset values for the QEI registers. +// +//***************************************************************************** +#define QEI_RV_CTL 0x00000000 // Configuration and control reg. +#define QEI_RV_STAT 0x00000000 // Status register +#define QEI_RV_POS 0x00000000 // Current position register +#define QEI_RV_MAXPOS 0x00000000 // Maximum position register +#define QEI_RV_LOAD 0x00000000 // Velocity timer load register +#define QEI_RV_TIME 0x00000000 // Velocity timer register +#define QEI_RV_COUNT 0x00000000 // Velocity pulse count register +#define QEI_RV_SPEED 0x00000000 // Velocity speed register +#define QEI_RV_INTEN 0x00000000 // Interrupt enable register +#define QEI_RV_RIS 0x00000000 // Raw interrupt status register +#define QEI_RV_ISC 0x00000000 // Interrupt status register + +#endif // __HW_QEI_H__ diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/hw_ssi.h b/Demo/CORTEX_LM3S811_GCC/hw_include/hw_ssi.h new file mode 100644 index 000000000..e4650af40 --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/hw_ssi.h @@ -0,0 +1,120 @@ +//***************************************************************************** +// +// hw_ssi.h - Macros used when accessing the SSI hardware. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +#ifndef __HW_SSI_H__ +#define __HW_SSI_H__ + +//***************************************************************************** +// +// The following define the offsets of the SSI registers. +// +//***************************************************************************** +#define SSI_O_CR0 0x00000000 // Control register 0 +#define SSI_O_CR1 0x00000004 // Control register 1 +#define SSI_O_DR 0x00000008 // Data register +#define SSI_O_SR 0x0000000C // Status register +#define SSI_O_CPSR 0x00000010 // Clock prescale register +#define SSI_O_IM 0x00000014 // Int mask set and clear register +#define SSI_O_RIS 0x00000018 // Raw interrupt register +#define SSI_O_MIS 0x0000001C // Masked interrupt register +#define SSI_O_ICR 0x00000020 // Interrupt clear register + +//***************************************************************************** +// +// The following define the bit fields in the SSI Control register 0. +// +//***************************************************************************** +#define SSI_CR0_SCR 0x0000FF00 // Serial clock rate +#define SSI_CR0_SPH 0x00000080 // SSPCLKOUT phase +#define SSI_CR0_SPO 0x00000040 // SSPCLKOUT polarity +#define SSI_CR0_FRF_MASK 0x00000030 // Frame format mask +#define SSI_CR0_FRF_MOTO 0x00000000 // Motorola SPI frame format +#define SSI_CR0_FRF_TI 0x00000010 // TI sync serial frame format +#define SSI_CR0_FRF_NMW 0x00000020 // National Microwire frame format +#define SSI_CR0_DSS 0x0000000F // Data size select +#define SSI_CR0_DSS_4 0x00000003 // 4 bit data +#define SSI_CR0_DSS_5 0x00000004 // 5 bit data +#define SSI_CR0_DSS_6 0x00000005 // 6 bit data +#define SSI_CR0_DSS_7 0x00000006 // 7 bit data +#define SSI_CR0_DSS_8 0x00000007 // 8 bit data +#define SSI_CR0_DSS_9 0x00000008 // 9 bit data +#define SSI_CR0_DSS_10 0x00000009 // 10 bit data +#define SSI_CR0_DSS_11 0x0000000A // 11 bit data +#define SSI_CR0_DSS_12 0x0000000B // 12 bit data +#define SSI_CR0_DSS_13 0x0000000C // 13 bit data +#define SSI_CR0_DSS_14 0x0000000D // 14 bit data +#define SSI_CR0_DSS_15 0x0000000E // 15 bit data +#define SSI_CR0_DSS_16 0x0000000F // 16 bit data + +//***************************************************************************** +// +// The following define the bit fields in the SSI Control register 1. +// +//***************************************************************************** +#define SSI_CR1_SOD 0x00000008 // Slave mode output disable +#define SSI_CR1_MS 0x00000004 // Master or slave mode select +#define SSI_CR1_SSE 0x00000002 // Sync serial port enable +#define SSI_CR1_LBM 0x00000001 // Loopback mode + +//***************************************************************************** +// +// The following define the bit fields in the SSI Status register. +// +//***************************************************************************** +#define SSI_SR_BSY 0x00000010 // SSI busy +#define SSI_SR_RFF 0x00000008 // RX FIFO full +#define SSI_SR_RNE 0x00000004 // RX FIFO not empty +#define SSI_SR_TNF 0x00000002 // TX FIFO not full +#define SSI_SR_TFE 0x00000001 // TX FIFO empty + +//***************************************************************************** +// +// The following define the bit fields in the SSI clock prescale register. +// +//***************************************************************************** +#define SSI_CPSR_CPSDVSR_MASK 0x000000FF // Clock prescale + +//***************************************************************************** +// +// The following define information concerning the SSI Data register. +// +//***************************************************************************** +#define TX_FIFO_SIZE (8) // Number of entries in the TX FIFO +#define RX_FIFO_SIZE (8) // Number of entries in the RX FIFO + +//***************************************************************************** +// +// The following define the bit fields in the interrupt mask set and clear, +// raw interrupt, masked interrupt, and interrupt clear registers. +// +//***************************************************************************** +#define SSI_INT_TXFF 0x00000008 // TX FIFO interrupt +#define SSI_INT_RXFF 0x00000004 // RX FIFO interrupt +#define SSI_INT_RXTO 0x00000002 // RX timeout interrupt +#define SSI_INT_RXOR 0x00000001 // RX overrun interrupt + +#endif // __HW_SSI_H__ diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/hw_sysctl.h b/Demo/CORTEX_LM3S811_GCC/hw_include/hw_sysctl.h new file mode 100644 index 000000000..cce5ad214 --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/hw_sysctl.h @@ -0,0 +1,409 @@ +//***************************************************************************** +// +// hw_sysctl.h - Macros used when accessing the system control hardware. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +#ifndef __HW_SYSCTL_H__ +#define __HW_SYSCTL_H__ + +//***************************************************************************** +// +// The following define the offsets of the system control registers. +// +//***************************************************************************** +#define SYSCTL_DID0 0x400fe000 // Device identification register 0 +#define SYSCTL_DID1 0x400fe004 // Device identification register 1 +#define SYSCTL_DC0 0x400fe008 // Device capabilities register 0 +#define SYSCTL_DC1 0x400fe010 // Device capabilities register 1 +#define SYSCTL_DC2 0x400fe014 // Device capabilities register 2 +#define SYSCTL_DC3 0x400fe018 // Device capabilities register 3 +#define SYSCTL_DC4 0x400fe01C // Device capabilities register 4 +#define SYSCTL_PBORCTL 0x400fe030 // POR/BOR reset control register +#define SYSCTL_LDOPCTL 0x400fe034 // LDO power control register +#define SYSCTL_SRCR0 0x400fe040 // Software reset control reg 0 +#define SYSCTL_SRCR1 0x400fe044 // Software reset control reg 1 +#define SYSCTL_SRCR2 0x400fe048 // Software reset control reg 2 +#define SYSCTL_RIS 0x400fe050 // Raw interrupt status register +#define SYSCTL_IMC 0x400fe054 // Interrupt mask/control register +#define SYSCTL_MISC 0x400fe058 // Interrupt status register +#define SYSCTL_RESC 0x400fe05c // Reset cause register +#define SYSCTL_RCC 0x400fe060 // Run-mode clock config register +#define SYSCTL_PLLCFG 0x400fe064 // PLL configuration register +#define SYSCTL_RCGC0 0x400fe100 // Run-mode clock gating register 0 +#define SYSCTL_RCGC1 0x400fe104 // Run-mode clock gating register 1 +#define SYSCTL_RCGC2 0x400fe108 // Run-mode clock gating register 2 +#define SYSCTL_SCGC0 0x400fe110 // Sleep-mode clock gating reg 0 +#define SYSCTL_SCGC1 0x400fe114 // Sleep-mode clock gating reg 1 +#define SYSCTL_SCGC2 0x400fe118 // Sleep-mode clock gating reg 2 +#define SYSCTL_DCGC0 0x400fe120 // Deep Sleep-mode clock gate reg 0 +#define SYSCTL_DCGC1 0x400fe124 // Deep Sleep-mode clock gate reg 1 +#define SYSCTL_DCGC2 0x400fe128 // Deep Sleep-mode clock gate reg 2 +#define SYSCTL_CLKVCLR 0x400fe150 // Clock verifcation clear register +#define SYSCTL_LDOARST 0x400fe160 // LDO reset control register + +//***************************************************************************** +// +// The following define the bit fields in the SYSCTL_DID0 register. +// +//***************************************************************************** +#define SYSCTL_DID0_VER_MASK 0x70000000 // DID0 version mask +#define SYSCTL_DID0_VER_0 0x00000000 // DID0 version 0 +#define SYSCTL_DID0_MAJ_MASK 0x0000FF00 // Major revision mask +#define SYSCTL_DID0_MAJ_A 0x00000000 // Major revision A +#define SYSCTL_DID0_MAJ_B 0x00000100 // Major revision B +#define SYSCTL_DID0_MIN_MASK 0x000000FF // Minor revision mask +#define SYSCTL_DID0_MIN_0 0x00000000 // Minor revision 0 +#define SYSCTL_DID0_MIN_1 0x00000001 // Minor revision 1 + +//***************************************************************************** +// +// The following define the bit fields in the SYSCTL_DID1 register. +// +//***************************************************************************** +#define SYSCTL_DID1_VER_MASK 0xF0000000 // Register version mask +#define SYSCTL_DID1_FAM_MASK 0x0F000000 // Family mask +#define SYSCTL_DID1_FAM_S 0x00000000 // Stellaris family +#define SYSCTL_DID1_PRTNO_MASK 0x00FF0000 // Part number mask +#define SYSCTL_DID1_PRTNO_101 0x00010000 // LM3S101 +#define SYSCTL_DID1_PRTNO_102 0x00020000 // LM3S102 +#define SYSCTL_DID1_PRTNO_301 0x00110000 // LM3S301 +#define SYSCTL_DID1_PRTNO_310 0x00120000 // LM3S310 +#define SYSCTL_DID1_PRTNO_315 0x00130000 // LM3S315 +#define SYSCTL_DID1_PRTNO_316 0x00140000 // LM3S316 +#define SYSCTL_DID1_PRTNO_328 0x00150000 // LM3S328 +#define SYSCTL_DID1_PRTNO_601 0x00210000 // LM3S601 +#define SYSCTL_DID1_PRTNO_610 0x00220000 // LM3S610 +#define SYSCTL_DID1_PRTNO_611 0x00230000 // LM3S611 +#define SYSCTL_DID1_PRTNO_612 0x00240000 // LM3S612 +#define SYSCTL_DID1_PRTNO_613 0x00250000 // LM3S613 +#define SYSCTL_DID1_PRTNO_615 0x00260000 // LM3S615 +#define SYSCTL_DID1_PRTNO_628 0x00270000 // LM3S628 +#define SYSCTL_DID1_PRTNO_801 0x00310000 // LM3S801 +#define SYSCTL_DID1_PRTNO_811 0x00320000 // LM3S811 +#define SYSCTL_DID1_PRTNO_812 0x00330000 // LM3S812 +#define SYSCTL_DID1_PRTNO_815 0x00340000 // LM3S815 +#define SYSCTL_DID1_PRTNO_828 0x00350000 // LM3S828 +#define SYSCTL_DID1_TEMP_MASK 0x000000E0 // Temperature range mask +#define SYSCTL_DID1_TEMP_C 0x00000000 // Commercial temp range (0..70C) +#define SYSCTL_DID1_TEMP_I 0x00000020 // Industrial temp range (-40..85C) +#define SYSCTL_DID1_PKG_MASK 0x00000018 // Package mask +#define SYSCTL_DID1_PKG_28SOIC 0x00000000 // 28-pin SOIC +#define SYSCTL_DID1_PKG_48QFP 0x00000008 // 48-pin QFP +#define SYSCTL_DID1_ROHS 0x00000004 // Part is RoHS compliant +#define SYSCTL_DID1_QUAL_MASK 0x00000003 // Qualification status mask +#define SYSCTL_DID1_QUAL_ES 0x00000000 // Engineering sample (unqualified) +#define SYSCTL_DID1_QUAL_PP 0x00000001 // Pilot production (unqualified) +#define SYSCTL_DID1_QUAL_FQ 0x00000002 // Fully qualified +#define SYSCTL_DID1_PRTNO_SHIFT 16 + +//***************************************************************************** +// +// The following define the bit fields in the SYSCTL_DC0 register. +// +//***************************************************************************** +#define SYSCTL_DC0_SRAMSZ_MASK 0xFFFF0000 // SRAM size mask +#define SYSCTL_DC0_SRAMSZ_2KB 0x00070000 // 2kB of SRAM +#define SYSCTL_DC0_SRAMSZ_4KB 0x000F0000 // 4kB of SRAM +#define SYSCTL_DC0_SRAMSZ_8KB 0x001F0000 // 8kB of SRAM +#define SYSCTL_DC0_FLASHSZ_MASK 0x0000FFFF // Flash size mask +#define SYSCTL_DC0_FLASHSZ_8KB 0x00000003 // 8kB of flash +#define SYSCTL_DC0_FLASHSZ_16KB 0x00000007 // 16kB of flash +#define SYSCTL_DC0_FLASHSZ_32KB 0x0000000F // 32kB of flash +#define SYSCTL_DC0_FLASHSZ_64KB 0x0000001F // 64kB of flash + +//***************************************************************************** +// +// The following define the bit fields in the SYSCTL_DC1 register. +// +//***************************************************************************** +#define SYSCTL_DC1_PWM 0x00100000 // PWM module present +#define SYSCTL_DC1_ADC 0x00010000 // ADC module present +#define SYSCTL_DC1_SYSDIV_MASK 0x0000F000 // Minimum system divider mask +#define SYSCTL_DC1_ADCSPD_MASK 0x00000F00 // ADC speed mask +#define SYSCTL_DC1_ADCSPD_1M 0x00000300 // 1Msps ADC +#define SYSCTL_DC1_ADCSPD_500K 0x00000200 // 500Ksps ADC +#define SYSCTL_DC1_ADCSPD_250K 0x00000100 // 250Ksps ADC +#define SYSCTL_DC1_ADCSPD_125K 0x00000000 // 125Ksps ADC +#define SYSCTL_DC1_MPU 0x00000080 // Cortex M3 MPU present +#define SYSCTL_DC1_TEMP 0x00000020 // Temperature sensor present +#define SYSCTL_DC1_PLL 0x00000010 // PLL present +#define SYSCTL_DC1_WDOG 0x00000008 // Watchdog present +#define SYSCTL_DC1_SWO 0x00000004 // Serial wire output present +#define SYSCTL_DC1_SWD 0x00000002 // Serial wire debug present +#define SYSCTL_DC1_JTAG 0x00000001 // JTAG debug present + +//***************************************************************************** +// +// The following define the bit fields in the SYSCTL_DC2 register. +// +//***************************************************************************** +#define SYSCTL_DC2_COMP2 0x04000000 // Analog comparator 2 present +#define SYSCTL_DC2_COMP1 0x02000000 // Analog comparator 1 present +#define SYSCTL_DC2_COMP0 0x01000000 // Analog comparator 0 present +#define SYSCTL_DC2_TIMER2 0x00040000 // Timer 2 present +#define SYSCTL_DC2_TIMER1 0x00020000 // Timer 1 present +#define SYSCTL_DC2_TIMER0 0x00010000 // Timer 0 present +#define SYSCTL_DC2_I2C 0x00001000 // I2C present +#define SYSCTL_DC2_QEI 0x00000100 // QEI present +#define SYSCTL_DC2_SSI 0x00000010 // SSI present +#define SYSCTL_DC2_UART1 0x00000002 // UART 1 present +#define SYSCTL_DC2_UART0 0x00000001 // UART 0 present + +//***************************************************************************** +// +// The following define the bit fields in the SYSCTL_DC3 register. +// +//***************************************************************************** +#define SYSCTL_DC3_32KHZ 0x80000000 // 32kHz pin present +#define SYSCTL_DC3_CCP5 0x20000000 // CCP5 pin present +#define SYSCTL_DC3_CCP4 0x10000000 // CCP4 pin present +#define SYSCTL_DC3_CCP3 0x08000000 // CCP3 pin present +#define SYSCTL_DC3_CCP2 0x04000000 // CCP2 pin present +#define SYSCTL_DC3_CCP1 0x02000000 // CCP1 pin present +#define SYSCTL_DC3_CCP0 0x01000000 // CCP0 pin present +#define SYSCTL_DC3_ADC7 0x00800000 // ADC7 pin present +#define SYSCTL_DC3_ADC6 0x00400000 // ADC6 pin present +#define SYSCTL_DC3_ADC5 0x00200000 // ADC5 pin present +#define SYSCTL_DC3_ADC4 0x00100000 // ADC4 pin present +#define SYSCTL_DC3_ADC3 0x00080000 // ADC3 pin present +#define SYSCTL_DC3_ADC2 0x00040000 // ADC2 pin present +#define SYSCTL_DC3_ADC1 0x00020000 // ADC1 pin present +#define SYSCTL_DC3_ADC0 0x00010000 // ADC0 pin present +#define SYSCTL_DC3_C2O 0x00004000 // C2o pin present +#define SYSCTL_DC3_C2PLUS 0x00002000 // C2+ pin present +#define SYSCTL_DC3_C2MINUS 0x00001000 // C2- pin present +#define SYSCTL_DC3_C1O 0x00000800 // C1o pin present +#define SYSCTL_DC3_C1PLUS 0x00000400 // C1+ pin present +#define SYSCTL_DC3_C1MINUS 0x00000200 // C1- pin present +#define SYSCTL_DC3_C0O 0x00000100 // C0o pin present +#define SYSCTL_DC3_C0PLUS 0x00000080 // C0+ pin present +#define SYSCTL_DC3_C0MINUS 0x00000040 // C0- pin present +#define SYSCTL_DC3_PWM5 0x00000020 // PWM5 pin present +#define SYSCTL_DC3_PWM4 0x00000010 // PWM4 pin present +#define SYSCTL_DC3_PWM3 0x00000008 // PWM3 pin present +#define SYSCTL_DC3_PWM2 0x00000004 // PWM2 pin present +#define SYSCTL_DC3_PWM1 0x00000002 // PWM1 pin present +#define SYSCTL_DC3_PWM0 0x00000001 // PWM0 pin present + +//***************************************************************************** +// +// The following define the bit fields in the SYSCTL_DC4 register. +// +//***************************************************************************** +#define SYSCTL_DC4_GPIOE 0x00000010 // GPIO port E present +#define SYSCTL_DC4_GPIOD 0x00000008 // GPIO port D present +#define SYSCTL_DC4_GPIOC 0x00000004 // GPIO port C present +#define SYSCTL_DC4_GPIOB 0x00000002 // GPIO port B present +#define SYSCTL_DC4_GPIOA 0x00000001 // GPIO port A present + +//***************************************************************************** +// +// The following define the bit fields in the SYSCTL_PBORCTL register. +// +//***************************************************************************** +#define SYSCTL_PBORCTL_BOR_MASK 0x0000FFFC // BOR wait timer +#define SYSCTL_PBORCTL_BORIOR 0x00000002 // BOR interrupt or reset +#define SYSCTL_PBORCTL_BORWT 0x00000001 // BOR wait and check for noise +#define SYSCTL_PBORCTL_BOR_SH 2 + +//***************************************************************************** +// +// The following define the bit fields in the SYSCTL_LDOPCTL register. +// +//***************************************************************************** +#define SYSCTL_LDOPCTL_MASK 0x0000003F // Voltage adjust mask +#define SYSCTL_LDOPCTL_2_25V 0x00000005 // LDO output of 2.25V +#define SYSCTL_LDOPCTL_2_30V 0x00000004 // LDO output of 2.30V +#define SYSCTL_LDOPCTL_2_35V 0x00000003 // LDO output of 2.35V +#define SYSCTL_LDOPCTL_2_40V 0x00000002 // LDO output of 2.40V +#define SYSCTL_LDOPCTL_2_45V 0x00000001 // LDO output of 2.45V +#define SYSCTL_LDOPCTL_2_50V 0x00000000 // LDO output of 2.50V +#define SYSCTL_LDOPCTL_2_55V 0x0000001F // LDO output of 2.55V +#define SYSCTL_LDOPCTL_2_60V 0x0000001E // LDO output of 2.60V +#define SYSCTL_LDOPCTL_2_65V 0x0000001D // LDO output of 2.65V +#define SYSCTL_LDOPCTL_2_70V 0x0000001C // LDO output of 2.70V +#define SYSCTL_LDOPCTL_2_75V 0x0000001B // LDO output of 2.75V + +//***************************************************************************** +// +// The following define the bit fields in the SYSCTL_SRCR0, SYSCTL_RCGC0, +// SYSCTL_SCGC0, and SYSCTL_DCGC0 registers. +// +//***************************************************************************** +#define SYSCTL_SET0_PWM 0x00100000 // PWM module +#define SYSCTL_SET0_ADC 0x00010000 // ADC module +#define SYSCTL_SET0_ADCSPD_MASK 0x00000F00 // ADC speed mask +#define SYSCTL_SET0_ADCSPD_1M 0x00000300 // 1Msps ADC +#define SYSCTL_SET0_ADCSPD_500K 0x00000200 // 500Ksps ADC +#define SYSCTL_SET0_ADCSPD_250K 0x00000100 // 250Ksps ADC +#define SYSCTL_SET0_ADCSPD_125K 0x00000000 // 125Ksps ADC +#define SYSCTL_SET0_WDOG 0x00000008 // Watchdog module + +//***************************************************************************** +// +// The following define the bit fields in the SYSCTL_SRCR1, SYSCTL_RCGC1, +// SYSCTL_SCGC1, and SYSCTL_DCGC1 registers. +// +//***************************************************************************** +#define SYSCTL_SET1_COMP2 0x04000000 // Analog comparator module 2 +#define SYSCTL_SET1_COMP1 0x02000000 // Analog comparator module 1 +#define SYSCTL_SET1_COMP0 0x01000000 // Analog comparator module 0 +#define SYSCTL_SET1_TIMER2 0x00040000 // Timer module 2 +#define SYSCTL_SET1_TIMER1 0x00020000 // Timer module 1 +#define SYSCTL_SET1_TIMER0 0x00010000 // Timer module 0 +#define SYSCTL_SET1_I2C 0x00001000 // I2C module +#define SYSCTL_SET1_QEI 0x00000100 // QEI module +#define SYSCTL_SET1_SSI 0x00000010 // SSI module +#define SYSCTL_SET1_UART1 0x00000002 // UART module 1 +#define SYSCTL_SET1_UART0 0x00000001 // UART module 0 + +//***************************************************************************** +// +// The following define the bit fields in the SYSCTL_SRCR2, SYSCTL_RCGC2, +// SYSCTL_SCGC2, and SYSCTL_DCGC2 registers. +// +//***************************************************************************** +#define SYSCTL_SET2_GPIOE 0x00000010 // GPIO E module +#define SYSCTL_SET2_GPIOD 0x00000008 // GPIO D module +#define SYSCTL_SET2_GPIOC 0x00000004 // GPIO C module +#define SYSCTL_SET2_GPIOB 0x00000002 // GPIO B module +#define SYSCTL_SET2_GPIOA 0x00000001 // GIPO A module + +//***************************************************************************** +// +// The following define the bit fields in the SYSCTL_RIS, SYSCTL_IMC, and +// SYSCTL_IMS registers. +// +//***************************************************************************** +#define SYSCTL_INT_PLL_LOCK 0x00000040 // PLL lock interrupt +#define SYSCTL_INT_CUR_LIMIT 0x00000020 // Current limit interrupt +#define SYSCTL_INT_IOSC_FAIL 0x00000010 // Internal oscillator failure int +#define SYSCTL_INT_MOSC_FAIL 0x00000008 // Main oscillator failure int +#define SYSCTL_INT_POR 0x00000004 // Power on reset interrupt +#define SYSCTL_INT_BOR 0x00000002 // Brown out interrupt +#define SYSCTL_INT_PLL_FAIL 0x00000001 // PLL failure interrupt + +//***************************************************************************** +// +// The following define the bit fields in the SYSCTL_RESC register. +// +//***************************************************************************** +#define SYSCTL_RESC_LDO 0x00000020 // LDO power OK lost reset +#define SYSCTL_RESC_SW 0x00000010 // Software reset +#define SYSCTL_RESC_WDOG 0x00000008 // Watchdog reset +#define SYSCTL_RESC_BOR 0x00000004 // Brown-out reset +#define SYSCTL_RESC_POR 0x00000002 // Power on reset +#define SYSCTL_RESC_EXT 0x00000001 // External reset + +//***************************************************************************** +// +// The following define the bit fields in the SYSCTL_RCC register. +// +//***************************************************************************** +#define SYSCTL_RCC_ACG 0x08000000 // Automatic clock gating +#define SYSCTL_RCC_SYSDIV_MASK 0x07800000 // System clock divider +#define SYSCTL_RCC_SYSDIV_2 0x00800000 // System clock /2 +#define SYSCTL_RCC_SYSDIV_3 0x01000000 // System clock /3 +#define SYSCTL_RCC_SYSDIV_4 0x01800000 // System clock /4 +#define SYSCTL_RCC_SYSDIV_5 0x02000000 // System clock /5 +#define SYSCTL_RCC_SYSDIV_6 0x02800000 // System clock /6 +#define SYSCTL_RCC_SYSDIV_7 0x03000000 // System clock /7 +#define SYSCTL_RCC_SYSDIV_8 0x03800000 // System clock /8 +#define SYSCTL_RCC_SYSDIV_9 0x04000000 // System clock /9 +#define SYSCTL_RCC_SYSDIV_10 0x04800000 // System clock /10 +#define SYSCTL_RCC_SYSDIV_11 0x05000000 // System clock /11 +#define SYSCTL_RCC_SYSDIV_12 0x05800000 // System clock /12 +#define SYSCTL_RCC_SYSDIV_13 0x06000000 // System clock /13 +#define SYSCTL_RCC_SYSDIV_14 0x06800000 // System clock /14 +#define SYSCTL_RCC_SYSDIV_15 0x07000000 // System clock /15 +#define SYSCTL_RCC_SYSDIV_16 0x07800000 // System clock /16 +#define SYSCTL_RCC_USE_SYSDIV 0x00400000 // Use sytem clock divider +#define SYSCTL_RCC_USE_PWMDIV 0x00100000 // Use PWM clock divider +#define SYSCTL_RCC_PWMDIV_MASK 0x000E0000 // PWM clock divider +#define SYSCTL_RCC_PWMDIV_2 0x00000000 // PWM clock /2 +#define SYSCTL_RCC_PWMDIV_4 0x00020000 // PWM clock /4 +#define SYSCTL_RCC_PWMDIV_8 0x00040000 // PWM clock /8 +#define SYSCTL_RCC_PWMDIV_16 0x00060000 // PWM clock /16 +#define SYSCTL_RCC_PWMDIV_32 0x00080000 // PWM clock /32 +#define SYSCTL_RCC_PWMDIV_64 0x000A0000 // PWM clock /64 +#define SYSCTL_RCC_PWRDN 0x00002000 // PLL power down +#define SYSCTL_RCC_OE 0x00001000 // PLL output enable +#define SYSCTL_RCC_BYPASS 0x00000800 // PLL bypass +#define SYSCTL_RCC_PLLVER 0x00000400 // PLL verification timer enable +#define SYSCTL_RCC_XTAL_MASK 0x000003C0 // Crystal attached to main osc +#define SYSCTL_RCC_XTAL_3_57MHZ 0x00000100 // Using a 3.579545MHz crystal +#define SYSCTL_RCC_XTAL_3_68MHz 0x00000140 // Using a 3.6864MHz crystal +#define SYSCTL_RCC_XTAL_4MHz 0x00000180 // Using a 4MHz crystal +#define SYSCTL_RCC_XTAL_4_09MHZ 0x000001C0 // Using a 4.096MHz crystal +#define SYSCTL_RCC_XTAL_4_91MHZ 0x00000200 // Using a 4.9152MHz crystal +#define SYSCTL_RCC_XTAL_5MHZ 0x00000240 // Using a 5MHz crystal +#define SYSCTL_RCC_XTAL_5_12MHZ 0x00000280 // Using a 5.12MHz crystal +#define SYSCTL_RCC_XTAL_6MHZ 0x000002C0 // Using a 6MHz crystal +#define SYSCTL_RCC_XTAL_6_14MHZ 0x00000300 // Using a 6.144MHz crystal +#define SYSCTL_RCC_XTAL_7_37MHZ 0x00000340 // Using a 7.3728MHz crystal +#define SYSCTL_RCC_XTAL_8MHZ 0x00000380 // Using a 8MHz crystal +#define SYSCTL_RCC_XTAL_8_19MHZ 0x000003C0 // Using a 8.192MHz crystal +#define SYSCTL_RCC_OSCSRC_MASK 0x00000030 // Oscillator input select +#define SYSCTL_RCC_OSCSRC_MAIN 0x00000000 // Use the main oscillator +#define SYSCTL_RCC_OSCSRC_INT 0x00000010 // Use the internal oscillator +#define SYSCTL_RCC_OSCSRC_INT4 0x00000020 // Use the internal oscillator / 4 +#define SYSCTL_RCC_IOSCVER 0x00000008 // Int. osc. verification timer en +#define SYSCTL_RCC_MOSCVER 0x00000004 // Main osc. verification timer en +#define SYSCTL_RCC_IOSCDIS 0x00000002 // Internal oscillator disable +#define SYSCTL_RCC_MOSCDIS 0x00000001 // Main oscillator disable +#define SYSCTL_RCC_SYSDIV_SHIFT 23 // Shift to the SYSDIV field +#define SYSCTL_RCC_PWMDIV_SHIFT 17 // Shift to the PWMDIV field +#define SYSCTL_RCC_XTAL_SHIFT 6 // Shift to the XTAL field +#define SYSCTL_RCC_OSCSRC_SHIFT 4 // Shift to the OSCSRC field + +//***************************************************************************** +// +// The following define the bit fields in the SYSCTL_PLLCFG register. +// +//***************************************************************************** +#define SYSCTL_PLLCFG_OD_MASK 0x0000C000 // Output divider +#define SYSCTL_PLLCFG_OD_1 0x00000000 // Output divider is 1 +#define SYSCTL_PLLCFG_OD_2 0x00004000 // Output divider is 2 +#define SYSCTL_PLLCFG_OD_4 0x00008000 // Output divider is 4 +#define SYSCTL_PLLCFG_F_MASK 0x00003FE0 // PLL multiplier +#define SYSCTL_PLLCFG_R_MASK 0x0000001F // Input predivider +#define SYSCTL_PLLCFG_F_SHIFT 5 +#define SYSCTL_PLLCFG_R_SHIFT 0 + +//***************************************************************************** +// +// The following define the bit fields in the SYSCTL_CLKVCLR register. +// +//***************************************************************************** +#define SYSCTL_CLKVCLR_CLR 0x00000001 // Clear clock verification fault + +//***************************************************************************** +// +// The following define the bit fields in the SYSCTL_LDOARST register. +// +//***************************************************************************** +#define SYSCTL_LDOARST_ARST 0x00000001 // Allow LDO to reset device + +#endif // __HW_SYSCTL_H__ diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/hw_timer.h b/Demo/CORTEX_LM3S811_GCC/hw_include/hw_timer.h new file mode 100644 index 000000000..210c3408e --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/hw_timer.h @@ -0,0 +1,235 @@ +//***************************************************************************** +// +// hw_timer.h - Defines and macros used when accessing the timer. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +#ifndef __HW_TIMER_H__ +#define __HW_TIMER_H__ + +//***************************************************************************** +// +// The following define the offsets of the timer registers. +// +//***************************************************************************** +#define TIMER_O_CFG 0x00000000 // Configuration register +#define TIMER_O_TAMR 0x00000004 // TimerA mode register +#define TIMER_O_TBMR 0x00000008 // TimerB mode register +#define TIMER_O_CTL 0x0000000C // Control register +#define TIMER_O_IMR 0x00000018 // Interrupt mask register +#define TIMER_O_RIS 0x0000001C // Interrupt status register +#define TIMER_O_MIS 0x00000020 // Masked interrupt status reg. +#define TIMER_O_ICR 0x00000024 // Interrupt clear register +#define TIMER_O_TAILR 0x00000028 // TimerA interval load register +#define TIMER_O_TBILR 0x0000002C // TimerB interval load register +#define TIMER_O_TAMATCHR 0x00000030 // TimerA match register +#define TIMER_O_TBMATCHR 0x00000034 // TimerB match register +#define TIMER_O_TAPR 0x00000038 // TimerA prescale register +#define TIMER_O_TBPR 0x0000003C // TimerB prescale register +#define TIMER_O_TAPMR 0x00000040 // TimerA prescale match register +#define TIMER_O_TBPMR 0x00000044 // TimerB prescale match register +#define TIMER_O_TAR 0x00000048 // TimerA register +#define TIMER_O_TBR 0x0000004C // TimerB register + +//***************************************************************************** +// +// The following define the reset values of the timer registers. +// +//***************************************************************************** +#define TIMER_RV_CFG 0x00000000 // Configuration register RV +#define TIMER_RV_TAMR 0x00000000 // TimerA mode register RV +#define TIMER_RV_TBMR 0x00000000 // TimerB mode register RV +#define TIMER_RV_CTL 0x00000000 // Control register RV +#define TIMER_RV_IMR 0x00000000 // Interrupt mask register RV +#define TIMER_RV_RIS 0x00000000 // Interrupt status register RV +#define TIMER_RV_MIS 0x00000000 // Masked interrupt status reg RV +#define TIMER_RV_ICR 0x00000000 // Interrupt clear register RV +#define TIMER_RV_TAILR 0xFFFFFFFF // TimerA interval load reg RV +#define TIMER_RV_TBILR 0x0000FFFF // TimerB interval load reg RV +#define TIMER_RV_TAMATCHR 0xFFFFFFFF // TimerA match register RV +#define TIMER_RV_TBMATCHR 0x0000FFFF // TimerB match register RV +#define TIMER_RV_TAPR 0x00000000 // TimerA prescale register RV +#define TIMER_RV_TBPR 0x00000000 // TimerB prescale register RV +#define TIMER_RV_TAPMR 0x00000000 // TimerA prescale match reg RV +#define TIMER_RV_TBPMR 0x00000000 // TimerB prescale match regi RV +#define TIMER_RV_TAR 0xFFFFFFFF // TimerA register RV +#define TIMER_RV_TBR 0x0000FFFF // TimerB register RV + +//***************************************************************************** +// +// The following define the bit fields in the TIMER_CFG register. +// +//***************************************************************************** +#define TIMER_CFG_CFG_MSK 0x00000007 // Configuration options mask +#define TIMER_CFG_16_BIT 0x00000004 // Two 16 bit timers +#define TIMER_CFG_32_BIT_RTC 0x00000001 // 32 bit RTC +#define TIMER_CFG_32_BIT_TIMER 0x00000000 // 32 bit timer + +//***************************************************************************** +// +// The following define the bit fields in the TIMER_TnMR register. +// +//***************************************************************************** +#define TIMER_TNMR_TNAMS 0x00000008 // Alternate mode select +#define TIMER_TNMR_TNCMR 0x00000004 // Capture mode - count or time +#define TIMER_TNMR_TNTMR_MSK 0x00000003 // Timer mode mask +#define TIMER_TNMR_TNTMR_CAP 0x00000003 // Mode - capture +#define TIMER_TNMR_TNTMR_PERIOD 0x00000002 // Mode - periodic +#define TIMER_TNMR_TNTMR_1_SHOT 0x00000001 // Mode - one shot + +//***************************************************************************** +// +// The following define the bit fields in the TIMER_CTL register. +// +//***************************************************************************** +#define TIMER_CTL_TBPWML 0x00004000 // TimerB PWM output level invert +#define TIMER_CTL_TBOTE 0x00002000 // TimerB output trigger enable +#define TIMER_CTL_TBEVENT_MSK 0x00000C00 // TimerB event mode mask +#define TIMER_CTL_TBEVENT_BOTH 0x00000C00 // TimerB event mode - both edges +#define TIMER_CTL_TBEVENT_NEG 0x00000400 // TimerB event mode - neg edge +#define TIMER_CTL_TBEVENT_POS 0x00000000 // TimerB event mode - pos edge +#define TIMER_CTL_TBSTALL 0x00000200 // TimerB stall enable +#define TIMER_CTL_TBEN 0x00000100 // TimerB enable +#define TIMER_CTL_TAPWML 0x00000040 // TimerA PWM output level invert +#define TIMER_CTL_TAOTE 0x00000020 // TimerA output trigger enable +#define TIMER_CTL_RTCEN 0x00000010 // RTC counter enable +#define TIMER_CTL_TAEVENT_MSK 0x0000000C // TimerA event mode mask +#define TIMER_CTL_TAEVENT_BOTH 0x0000000C // TimerA event mode - both edges +#define TIMER_CTL_TAEVENT_NEG 0x00000004 // TimerA event mode - neg edge +#define TIMER_CTL_TAEVENT_POS 0x00000000 // TimerA event mode - pos edge +#define TIMER_CTL_TASTALL 0x00000002 // TimerA stall enable +#define TIMER_CTL_TAEN 0x00000001 // TimerA enable + +//***************************************************************************** +// +// The following define the bit fields in the TIMER_IMR register. +// +//***************************************************************************** +#define TIMER_IMR_CBEIM 0x00000400 // CaptureB event interrupt mask +#define TIMER_IMR_CBMIM 0x00000200 // CaptureB match interrupt mask +#define TIMER_IMR_TBTOIM 0x00000100 // TimerB time out interrupt mask +#define TIMER_IMR_RTCIM 0x00000008 // RTC interrupt mask +#define TIMER_IMR_CAEIM 0x00000004 // CaptureA event interrupt mask +#define TIMER_IMR_CAMIM 0x00000002 // CaptureA match interrupt mask +#define TIMER_IMR_TATOIM 0x00000001 // TimerA time out interrupt mask + +//***************************************************************************** +// +// The following define the bit fields in the TIMER_RIS register. +// +//***************************************************************************** +#define TIMER_RIS_CBERIS 0x00000400 // CaptureB event raw int status +#define TIMER_RIS_CBMRIS 0x00000200 // CaptureB match raw int status +#define TIMER_RIS_TBTORIS 0x00000100 // TimerB time out raw int status +#define TIMER_RIS_RTCRIS 0x00000008 // RTC raw int status +#define TIMER_RIS_CAERIS 0x00000004 // CaptureA event raw int status +#define TIMER_RIS_CAMRIS 0x00000002 // CaptureA match raw int status +#define TIMER_RIS_TATORIS 0x00000001 // TimerA time out raw int status + +//***************************************************************************** +// +// The following define the bit fields in the TIMER_MIS register. +// +//***************************************************************************** +#define TIMER_RIS_CBEMIS 0x00000400 // CaptureB event masked int status +#define TIMER_RIS_CBMMIS 0x00000200 // CaptureB match masked int status +#define TIMER_RIS_TBTOMIS 0x00000100 // TimerB time out masked int stat +#define TIMER_RIS_RTCMIS 0x00000008 // RTC masked int status +#define TIMER_RIS_CAEMIS 0x00000004 // CaptureA event masked int status +#define TIMER_RIS_CAMMIS 0x00000002 // CaptureA match masked int status +#define TIMER_RIS_TATOMIS 0x00000001 // TimerA time out masked int stat + +//***************************************************************************** +// +// The following define the bit fields in the TIMER_ICR register. +// +//***************************************************************************** +#define TIMER_ICR_CBECINT 0x00000400 // CaptureB event interrupt clear +#define TIMER_ICR_CBMCINT 0x00000200 // CaptureB match interrupt clear +#define TIMER_ICR_TBTOCINT 0x00000100 // TimerB time out interrupt clear +#define TIMER_ICR_RTCCINT 0x00000008 // RTC interrupt clear +#define TIMER_ICR_CAECINT 0x00000004 // CaptureA event interrupt clear +#define TIMER_ICR_CAMCINT 0x00000002 // CaptureA match interrupt clear +#define TIMER_ICR_TATOCINT 0x00000001 // TimerA time out interrupt clear + +//***************************************************************************** +// +// The following define the bit fields in the TIMER_TAILR register. +// +//***************************************************************************** +#define TIMER_TAILR_TAILRH 0xFFFF0000 // TimerB load val in 32 bit mode +#define TIMER_TAILR_TAILRL 0x0000FFFF // TimerA interval load value + +//***************************************************************************** +// +// The following defines the bit fields in the TIMER_TBILR register. +// +//***************************************************************************** +#define TIMER_TBILR_TBILRL 0x0000FFFF // TimerB interval load value + +//***************************************************************************** +// +// The following define the bit fields in the TIMER_TAMATCHR register. +// +//***************************************************************************** +#define TIMER_TAMATCHR_TAMRH 0xFFFF0000 // TimerB match val in 32 bit mode +#define TIMER_TAMATCHR_TAMRL 0x0000FFFF // TimerA match value + +//***************************************************************************** +// +// The following defines the bit fields in the TIMER_TBMATCHR register. +// +//***************************************************************************** +#define TIMER_TBMATCHR_TBMRL 0x0000FFFF // TimerB match load value + +//***************************************************************************** +// +// The following defines the bit fields in the TIMER_TnPR register. +// +//***************************************************************************** +#define TIMER_TNPR_TNPSR 0x000000FF // TimerN prescale value + +//***************************************************************************** +// +// The following defines the bit fields in the TIMER_TnPMR register. +// +//***************************************************************************** +#define TIMER_TNPMR_TNPSMR 0x000000FF // TimerN prescale match value + +//***************************************************************************** +// +// The following define the bit fields in the TIMER_TAR register. +// +//***************************************************************************** +#define TIMER_TAR_TARH 0xFFFF0000 // TimerB val in 32 bit mode +#define TIMER_TAR_TARL 0x0000FFFF // TimerA value + +//***************************************************************************** +// +// The following defines the bit fields in the TIMER_TBR register. +// +//***************************************************************************** +#define TIMER_TBR_TBRL 0x0000FFFF // TimerB value + +#endif // __HW_TIMER_H__ diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/hw_types.h b/Demo/CORTEX_LM3S811_GCC/hw_include/hw_types.h new file mode 100644 index 000000000..ec05e5415 --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/hw_types.h @@ -0,0 +1,67 @@ +//***************************************************************************** +// +// hw_types.h - Common types and macros. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +#ifndef __HW_TYPES_H__ +#define __HW_TYPES_H__ + +//***************************************************************************** +// +// Define a boolean type, and values for true and false. +// +//***************************************************************************** +typedef unsigned char tBoolean; + +#ifndef true +#define true 1 +#endif + +#ifndef false +#define false 0 +#endif + +//***************************************************************************** +// +// Macros for hardware access, both direct and via the bit-band region. +// +//***************************************************************************** +#define HWREG(x) \ + (*((volatile unsigned long *)(x))) +#define HWREGH(x) \ + (*((volatile unsigned short *)(x))) +#define HWREGB(x) \ + (*((volatile unsigned char *)(x))) +#define HWREGBITW(x, b) \ + HWREG(((unsigned long)(x) & 0xF0000000) | 0x02000000 | \ + (((unsigned long)(x) & 0x000FFFFF) << 5) | ((b) << 2)) +#define HWREGBITH(x, b) \ + HWREGH(((unsigned long)(x) & 0xF0000000) | 0x02000000 | \ + (((unsigned long)(x) & 0x000FFFFF) << 5) | ((b) << 2)) +#define HWREGBITB(x, b) \ + HWREGB(((unsigned long)(x) & 0xF0000000) | 0x02000000 | \ + (((unsigned long)(x) & 0x000FFFFF) << 5) | ((b) << 2)) + +#endif // __HW_TYPES_H__ diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/hw_uart.h b/Demo/CORTEX_LM3S811_GCC/hw_include/hw_uart.h new file mode 100644 index 000000000..6f421b64e --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/hw_uart.h @@ -0,0 +1,239 @@ +//***************************************************************************** +// +// hw_uart.h - Macros and defines used when accessing the UART hardware +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +#ifndef __HW_UART_H__ +#define __HW_UART_H__ + +//***************************************************************************** +// +// UART Register Offsets. +// +//***************************************************************************** +#define UART_O_DR 0x00000000 // Data Register +#define UART_O_RSR 0x00000004 // Receive Status Register (read) +#define UART_O_ECR 0x00000004 // Error Clear Register (write) +#define UART_O_FR 0x00000018 // Flag Register (read only) +#define UART_O_IBRD 0x00000024 // Integer Baud Rate Divisor Reg +#define UART_O_FBRD 0x00000028 // Fractional Baud Rate Divisor Reg +#define UART_O_LCR_H 0x0000002C // Line Control Register, HIGH byte +#define UART_O_CTL 0x00000030 // Control Register +#define UART_O_IFLS 0x00000034 // Interrupt FIFO Level Select Reg +#define UART_O_IM 0x00000038 // Interrupt Mask Set/Clear Reg +#define UART_O_RIS 0x0000003C // Raw Interrupt Status Register +#define UART_O_MIS 0x00000040 // Masked Interrupt Status Register +#define UART_O_ICR 0x00000044 // Interrupt Clear Register +#define UART_O_PeriphID4 0x00000FD0 // +#define UART_O_PeriphID5 0x00000FD4 // +#define UART_O_PeriphID6 0x00000FD8 // +#define UART_O_PeriphID7 0x00000FDC // +#define UART_O_PeriphID0 0x00000FE0 // +#define UART_O_PeriphID1 0x00000FE4 // +#define UART_O_PeriphID2 0x00000FE8 // +#define UART_O_PeriphID3 0x00000FEC // +#define UART_O_PCellID0 0x00000FF0 // +#define UART_O_PCellID1 0x00000FF4 // +#define UART_O_PCellID2 0x00000FF8 // +#define UART_O_PCellID3 0x00000FFC // + +//***************************************************************************** +// +// Data Register bits +// +//***************************************************************************** +#define UART_DR_OE 0x00000800 // Overrun Error +#define UART_DR_BE 0x00000400 // Break Error +#define UART_DR_PE 0x00000200 // Parity Error +#define UART_DR_FE 0x00000100 // Framing Error +#define UART_DR_DATA_MASK 0x000000FF // UART data + +//***************************************************************************** +// +// Receive Status Register bits +// +//***************************************************************************** +#define UART_RSR_OE 0x00000008 // Overrun Error +#define UART_RSR_BE 0x00000004 // Break Error +#define UART_RSR_PE 0x00000002 // Parity Error +#define UART_RSR_FE 0x00000001 // Framing Error + +//***************************************************************************** +// +// Flag Register bits +// +//***************************************************************************** +#define UART_FR_TXFE 0x00000080 // TX FIFO Empty +#define UART_FR_RXFF 0x00000040 // RX FIFO Full +#define UART_FR_TXFF 0x00000020 // TX FIFO Full +#define UART_FR_RXFE 0x00000010 // RX FIFO Empty +#define UART_FR_BUSY 0x00000008 // UART Busy + +//***************************************************************************** +// +// Integer baud-rate divisor +// +//***************************************************************************** +#define UART_IBRD_DIVINT_MASK 0x0000FFFF // Integer baud-rate divisor + +//***************************************************************************** +// +// Fractional baud-rate divisor +// +//***************************************************************************** +#define UART_FBRD_DIVFRAC_MASK 0x0000003F // Fractional baud-rate divisor + +//***************************************************************************** +// +// Line Control Register High bits +// +//***************************************************************************** +#define UART_LCR_H_SPS 0x00000080 // Stick Parity Select +#define UART_LCR_H_WLEN 0x00000060 // Word length +#define UART_LCR_H_WLEN_8 0x00000060 // 8 bit data +#define UART_LCR_H_WLEN_7 0x00000040 // 7 bit data +#define UART_LCR_H_WLEN_6 0x00000020 // 6 bit data +#define UART_LCR_H_WLEN_5 0x00000000 // 5 bit data +#define UART_LCR_H_FEN 0x00000010 // Enable FIFO +#define UART_LCR_H_STP2 0x00000008 // Two Stop Bits Select +#define UART_LCR_H_EPS 0x00000004 // Even Parity Select +#define UART_LCR_H_PEN 0x00000002 // Parity Enable +#define UART_LCR_H_BRK 0x00000001 // Send Break + +//***************************************************************************** +// +// Control Register bits +// +//***************************************************************************** +#define UART_CTL_RXE 0x00000200 // Receive Enable +#define UART_CTL_TXE 0x00000100 // Transmit Enable +#define UART_CTL_LBE 0x00000080 // Loopback Enable +#define UART_CTL_UARTEN 0x00000001 // UART Enable + +//***************************************************************************** +// +// Interrupt FIFO Level Select Register bits +// +//***************************************************************************** +#define UART_IFLS_RX1_8 0x00000000 // 1/8 Full +#define UART_IFLS_RX2_8 0x00000010 // 1/4 Full +#define UART_IFLS_RX4_8 0x00000020 // 1/2 Full +#define UART_IFLS_RX6_8 0x00000030 // 3/4 Full +#define UART_IFLS_RX7_8 0x00000040 // 7/8 Full +#define UART_IFLS_TX1_8 0x00000000 // 1/8 Full +#define UART_IFLS_TX2_8 0x00000001 // 1/4 Full +#define UART_IFLS_TX4_8 0x00000002 // 1/2 Full +#define UART_IFLS_TX6_8 0x00000003 // 3/4 Full +#define UART_IFLS_TX7_8 0x00000004 // 7/8 Full + +//***************************************************************************** +// +// Interrupt Mask Set/Clear Register bits +// +//***************************************************************************** +#define UART_IM_OEIM 0x00000400 // Overrun Error Interrupt Mask +#define UART_IM_BEIM 0x00000200 // Break Error Interrupt Mask +#define UART_IM_PEIM 0x00000100 // Parity Error Interrupt Mask +#define UART_IM_FEIM 0x00000080 // Framing Error Interrupt Mask +#define UART_IM_RTIM 0x00000040 // Receive Timeout Interrupt Mask +#define UART_IM_TXIM 0x00000020 // Transmit Interrupt Mask +#define UART_IM_RXIM 0x00000010 // Receive Interrupt Mask + +//***************************************************************************** +// +// Raw Interrupt Status Register +// +//***************************************************************************** +#define UART_RIS_OERIS 0x00000400 // Overrun Error Interrupt Status +#define UART_RIS_BERIS 0x00000200 // Break Error Interrupt Status +#define UART_RIS_PERIS 0x00000100 // Parity Error Interrupt Status +#define UART_RIS_FERIS 0x00000080 // Framing Error Interrupt Status +#define UART_RIS_RTRIS 0x00000040 // Receive Timeout Interrupt Status +#define UART_RIS_TXRIS 0x00000020 // Transmit Interrupt Status +#define UART_RIS_RXRIS 0x00000010 // Receive Interrupt Status + +//***************************************************************************** +// +// Masked Interrupt Status Register +// +//***************************************************************************** +#define UART_MIS_OEMIS 0x00000400 // Overrun Error Interrupt Status +#define UART_MIS_BEMIS 0x00000200 // Break Error Interrupt Status +#define UART_MIS_PEMIS 0x00000100 // Parity Error Interrupt Status +#define UART_MIS_FEMIS 0x00000080 // Framing Error Interrupt Status +#define UART_MIS_RTMIS 0x00000040 // Receive Timeout Interrupt Status +#define UART_MIS_TXMIS 0x00000020 // Transmit Interrupt Status +#define UART_MIS_RXMIS 0x00000010 // Receive Interrupt Status + +//***************************************************************************** +// +// Interrupt Clear Register bits +// +//***************************************************************************** +#define UART_ICR_OEIC 0x00000400 // Overrun Error Interrupt Clear +#define UART_ICR_BEIC 0x00000200 // Break Error Interrupt Clear +#define UART_ICR_PEIC 0x00000100 // Parity Error Interrupt Clear +#define UART_ICR_FEIC 0x00000080 // Framing Error Interrupt Clear +#define UART_ICR_RTIC 0x00000040 // Receive Timeout Interrupt Clear +#define UART_ICR_TXIC 0x00000020 // Transmit Interrupt Clear +#define UART_ICR_RXIC 0x00000010 // Receive Interrupt Clear + +#define UART_RSR_ANY (UART_RSR_OE | \ + UART_RSR_BE | \ + UART_RSR_PE | \ + UART_RSR_FE) + +//***************************************************************************** +// +// Reset Values for UART Registers. +// +//***************************************************************************** +#define UART_RV_DR 0x00000000 +#define UART_RV_RSR 0x00000000 +#define UART_RV_ECR 0x00000000 +#define UART_RV_FR 0x00000090 +#define UART_RV_IBRD 0x00000000 +#define UART_RV_FBRD 0x00000000 +#define UART_RV_LCR_H 0x00000000 +#define UART_RV_CTL 0x00000300 +#define UART_RV_IFLS 0x00000012 +#define UART_RV_IM 0x00000000 +#define UART_RV_RIS 0x00000000 +#define UART_RV_MIS 0x00000000 +#define UART_RV_ICR 0x00000000 +#define UART_RV_PeriphID4 0x00000000 +#define UART_RV_PeriphID5 0x00000000 +#define UART_RV_PeriphID6 0x00000000 +#define UART_RV_PeriphID7 0x00000000 +#define UART_RV_PeriphID0 0x00000011 +#define UART_RV_PeriphID1 0x00000000 +#define UART_RV_PeriphID2 0x00000018 +#define UART_RV_PeriphID3 0x00000001 +#define UART_RV_PCellID0 0x0000000D +#define UART_RV_PCellID1 0x000000F0 +#define UART_RV_PCellID2 0x00000005 +#define UART_RV_PCellID3 0x000000B1 + +#endif // __HW_UART_H__ diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/hw_watchdog.h b/Demo/CORTEX_LM3S811_GCC/hw_include/hw_watchdog.h new file mode 100644 index 000000000..2b013ad84 --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/hw_watchdog.h @@ -0,0 +1,116 @@ +//***************************************************************************** +// +// hw_watchdog.h - Macros used when accessing the Watchdog Timer hardware. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +#ifndef __HW_WATCHDOG_H__ +#define __HW_WATCHDOG_H__ + +//***************************************************************************** +// +// The following define the offsets of the Watchdog Timer registers. +// +//***************************************************************************** +#define WDT_O_LOAD 0x00000000 // Load register +#define WDT_O_VALUE 0x00000004 // Current value register +#define WDT_O_CTL 0x00000008 // Control register +#define WDT_O_ICR 0x0000000C // Interrupt clear register +#define WDT_O_RIS 0x00000010 // Raw interrupt status register +#define WDT_O_MIS 0x00000014 // Masked interrupt status register +#define WDT_O_TEST 0x00000418 // Test register +#define WDT_O_LOCK 0x00000C00 // Lock register +#define WDT_O_PeriphID4 0x00000FD0 // +#define WDT_O_PeriphID5 0x00000FD4 // +#define WDT_O_PeriphID6 0x00000FD8 // +#define WDT_O_PeriphID7 0x00000FDC // +#define WDT_O_PeriphID0 0x00000FE0 // +#define WDT_O_PeriphID1 0x00000FE4 // +#define WDT_O_PeriphID2 0x00000FE8 // +#define WDT_O_PeriphID3 0x00000FEC // +#define WDT_O_PCellID0 0x00000FF0 // +#define WDT_O_PCellID1 0x00000FF4 // +#define WDT_O_PCellID2 0x00000FF8 // +#define WDT_O_PCellID3 0x00000FFC // + +//***************************************************************************** +// +// The following define the bit fields in the WDT_CTL register. +// +//***************************************************************************** +#define WDT_CTL_RESEN 0x00000002 // Enable reset output +#define WDT_CTL_INTEN 0x00000001 // Enable the WDT counter and int + +//***************************************************************************** +// +// The following define the bit fields in the WDT_ISR, WDT_RIS, and WDT_MIS +// registers. +// +//***************************************************************************** +#define WDT_INT_TIMEOUT 0x00000001 // Watchdog timer expired + +//***************************************************************************** +// +// The following define the bit fields in the WDT_TEST register. +// +//***************************************************************************** +#define WDT_TEST_STALL 0x00000100 // Watchdog stall enable +#ifndef DEPRECATED +#define WDT_TEST_STALL_EN 0x00000100 // Watchdog stall enable +#endif + +//***************************************************************************** +// +// The following define the bit fields in the WDT_LOCK register. +// +//***************************************************************************** +#define WDT_LOCK_LOCKED 0x00000001 // Watchdog timer is locked +#define WDT_LOCK_UNLOCKED 0x00000000 // Watchdog timer is unlocked +#define WDT_LOCK_UNLOCK 0x1ACCE551 // Unlocks the watchdog timer + +//***************************************************************************** +// +// The following define the reset values for the WDT registers. +// +//***************************************************************************** +#define WDT_RV_LOAD 0xFFFFFFFF // Load register +#define WDT_RV_VALUE 0xFFFFFFFF // Current value register +#define WDT_RV_CTL 0x00000000 // Control register +#define WDT_RV_RIS 0x00000000 // Raw interrupt status register +#define WDT_RV_MIS 0x00000000 // Masked interrupt status register +#define WDT_RV_LOCK 0x00000000 // Lock register +#define WDT_RV_PeriphID4 0x00000000 // +#define WDT_RV_PeriphID5 0x00000000 // +#define WDT_RV_PeriphID6 0x00000000 // +#define WDT_RV_PeriphID7 0x00000000 // +#define WDT_RV_PeriphID0 0x00000005 // +#define WDT_RV_PeriphID1 0x00000018 // +#define WDT_RV_PeriphID2 0x00000018 // +#define WDT_RV_PeriphID3 0x00000001 // +#define WDT_RV_PCellID0 0x0000000D // +#define WDT_RV_PCellID1 0x000000F0 // +#define WDT_RV_PCellID2 0x00000005 // +#define WDT_RV_PCellID3 0x000000B1 // + +#endif // __HW_WATCHDOG_H__ diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/i2c.c b/Demo/CORTEX_LM3S811_GCC/hw_include/i2c.c new file mode 100644 index 000000000..b460ad603 --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/i2c.c @@ -0,0 +1,972 @@ +//***************************************************************************** +// +// i2c.c - Driver for Inter-IC (I2C) bus block. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +//***************************************************************************** +// +//! \addtogroup i2c_api +//! @{ +// +//***************************************************************************** + +#include "../hw_i2c.h" +#include "../hw_ints.h" +#include "../hw_memmap.h" +#include "../hw_types.h" +#include "debug.h" +#include "i2c.h" +#include "interrupt.h" +#include "sysctl.h" + +//***************************************************************************** +// +//! Initializes the I2C Master block. +//! +//! \param ulBase base address of the I2C Master module +//! \param bFast set up for fast data transfers +//! +//! This function initializes operation of the I2C Master block. Upon +//! successful initialization of the I2C block, this function will have +//! set the bus speed for the master, and will have enabled the I2C Master +//! block. +//! +//! If the parameter \e bFast is \b true, then the master block will be +//! set up to transfer data at 400 kbps; otherwise, it will be set up to +//! transfer data at 100 kbps. +//! +//! The I2C clocking is dependent upon the system clock rate returned by +//! SysCtlClockGet(); if it does not return the correct system clock rate then +//! the I2C clock rate will be incorrect. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_masterinit) || defined(BUILD_ALL) || defined(DOXYGEN) +void +I2CMasterInit(unsigned long ulBase, tBoolean bFast) +{ + unsigned long ulSysClk; + unsigned long ulSCLFreq; + unsigned long ulTPR; + + // + // Check the arguments. + // + ASSERT(ulBase == I2C_MASTER_BASE); + + // + // Must enable the device before doing anything else. + // + I2CMasterEnable(ulBase); + + // + // Get the system clock speed. + // + ulSysClk = SysCtlClockGet(); + + // + // Get the desired SCL speed. + // + if(bFast == true) + { + ulSCLFreq = I2C_SCL_FAST; + } + else + { + ulSCLFreq = I2C_SCL_STANDARD; + } + + // + // Compute the clock divider that achieves the fastest speed less than or + // equal to the desired speed. The numerator is biases to favor a larger + // clock divider so that the resulting clock is always less than or equal + // to the desired clock, never greater. + // + ulTPR = (((ulSysClk + (2 * I2C_MASTER_TPR_SCL * ulSCLFreq) - 1) / + (2 * I2C_MASTER_TPR_SCL * ulSCLFreq)) - 1); + HWREG(ulBase + I2C_MASTER_O_TPR) = ulTPR; +} +#endif + +//***************************************************************************** +// +//! Initializes the I2C Slave block. +//! +//! \param ulBase base address of the I2C Slave module +//! \param ucSlaveAddr 7-bit slave address +//! +//! This function initializes operation of the I2C Slave block. Upon +//! successful initialization of the I2C blocks, this function will have +//! set the slave address and have enabled the I2C Slave block. +//! +//! The parameter \e ucSlaveAddr is the value that will be compared +//! against the slave address sent by an I2C master. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_slaveinit) || defined(BUILD_ALL) || defined(DOXYGEN) +void +I2CSlaveInit(unsigned long ulBase, unsigned char ucSlaveAddr) +{ + // + // Check the arguments. + // + ASSERT(ulBase == I2C_SLAVE_BASE); + ASSERT(!(ucSlaveAddr & 0x80)); + + // + // Must enable the device before doing anything else. + // + I2CSlaveEnable(ulBase); + + // + // Set up the slave address. + // + HWREG(ulBase + I2C_SLAVE_O_OAR) = ucSlaveAddr; +} +#endif + +//***************************************************************************** +// +//! Enables the I2C Master block. +//! +//! \param ulBase base address of the I2C Master module +//! +//! This will enable operation of the I2C Master block. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_masterenable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +I2CMasterEnable(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == I2C_MASTER_BASE); + + // + // Enable the master block. + // + HWREG(ulBase + I2C_MASTER_O_CR) |= I2C_MASTER_CR_MFE; +} +#endif + +//***************************************************************************** +// +//! Enables the I2C Slave block. +//! +//! \param ulBase base address of the I2C Slave module +//! +//! This will enable operation of the I2C Slave block. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_slaveenable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +I2CSlaveEnable(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == I2C_SLAVE_BASE); + + // + // Enable the clock to the slave block. + // + HWREG(ulBase - I2C_O_SLAVE + I2C_MASTER_O_CR) |= I2C_MASTER_CR_SFE; + + // + // Enable the slave. + // + HWREG(ulBase + I2C_SLAVE_O_CSR) = I2C_SLAVE_CSR_DA; +} +#endif + +//***************************************************************************** +// +//! Disables the I2C master block. +//! +//! \param ulBase base address of the I2C Master module +//! +//! This will disable operation of the I2C master block. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_masterdisable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +I2CMasterDisable(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == I2C_MASTER_BASE); + + // + // Disable the master block. + // + HWREG(ulBase + I2C_MASTER_O_CR) &= ~(I2C_MASTER_CR_MFE); +} +#endif + +//***************************************************************************** +// +//! Disables the I2C slave block. +//! +//! \param ulBase base address of the I2C Slave module +//! +//! This will disable operation of the I2C slave block. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_slavedisable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +I2CSlaveDisable(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == I2C_SLAVE_BASE); + + // + // Disable the slave. + // + HWREG(ulBase + I2C_SLAVE_O_CSR) = 0; + + // + // Disable the clock to the slave block. + // + HWREG(ulBase - I2C_O_SLAVE + I2C_MASTER_O_CR) &= ~(I2C_MASTER_CR_SFE); +} +#endif + +//***************************************************************************** +// +//! Registers an interrupt handler for the I2C module +//! +//! \param ulBase base address of the I2C module +//! \param pfnHandler is a pointer to the function to be called when the +//! synchronous serial interface interrupt occurs. +//! +//! This sets the handler to be called when an I2C interrupt occurs. This +//! will enable the global interrupt in the interrupt controller; specific I2C +//! interrupts must be enabled via I2CMasterIntEnable() and +//! I2CSlaveIntEnable(). If necessary, it is the interrupt handler's +//! responsibility to clear the interrupt source via I2CMasterIntClear() and +//! I2CSlaveIntClear(). +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intregister) || defined(BUILD_ALL) || defined(DOXYGEN) +void +I2CIntRegister(unsigned long ulBase, void (*pfnHandler)(void)) +{ + // + // Check the arguments. + // + ASSERT(ulBase == I2C_MASTER_BASE); + + // + // Register the interrupt handler, returning an error if an error occurs. + // + IntRegister(INT_I2C, pfnHandler); + + // + // Enable the I2C interrupt. + // + IntEnable(INT_I2C); +} +#endif + +//***************************************************************************** +// +//! Unregisters an interrupt handler for the I2C module. +//! +//! \param ulBase base address of the I2C module +//! +//! This function will clear the handler to be called when an I2C +//! interrupt occurs. This will also mask off the interrupt in the interrupt +//! controller so that the interrupt handler no longer is called. +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intunregister) || defined(BUILD_ALL) || defined(DOXYGEN) +void +I2CIntUnregister(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == I2C_MASTER_BASE); + + // + // Disable the interrupt. + // + IntDisable(INT_I2C); + + // + // Unregister the interrupt handler. + // + IntUnregister(INT_I2C); +} +#endif + +//***************************************************************************** +// +//! Enables the I2C Master interrupt. +//! +//! \param ulBase base address of the I2C Master module +//! +//! Enables the I2C Master interrupt source. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_masterintenable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +I2CMasterIntEnable(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == I2C_MASTER_BASE); + + // + // Enable the master interrupt. + // + HWREG(ulBase + I2C_MASTER_O_IMR) = 1; +} +#endif + +//***************************************************************************** +// +//! Enables the I2C Slave interrupt. +//! +//! \param ulBase base address of the I2C Slave module +//! +//! Enables the I2C Slave interrupt source. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_slaveintenable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +I2CSlaveIntEnable(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == I2C_SLAVE_BASE); + + // + // Enable the slave interrupt. + // + HWREG(ulBase + I2C_SLAVE_O_IM) = 1; +} +#endif + +//***************************************************************************** +// +//! Disables the I2C Master interrupt. +//! +//! \param ulBase base address of the I2C Master module +//! +//! Disables the I2C Master interrupt source. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_masterintdisable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +I2CMasterIntDisable(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == I2C_MASTER_BASE); + + // + // Disable the master interrupt. + // + HWREG(ulBase + I2C_MASTER_O_IMR) = 0; +} +#endif + +//***************************************************************************** +// +//! Disables the I2C Slave interrupt. +//! +//! \param ulBase base address of the I2C Slave module +//! +//! Disables the I2C Slave interrupt source. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_slaveintdisable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +I2CSlaveIntDisable(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == I2C_SLAVE_BASE); + + // + // Disable the slave interrupt. + // + HWREG(ulBase + I2C_SLAVE_O_IM) = 0; +} +#endif + +//***************************************************************************** +// +//! Gets the current I2C Master interrupt status. +//! +//! \param ulBase base address of the I2C Master module +//! \param bMasked is false if the raw interrupt status is requested and +//! true if the masked interrupt status is requested. +//! +//! This returns the interrupt status for the I2C Master module. +//! Either the raw interrupt status or the status of interrupts that are +//! allowed to reflect to the processor can be returned. +//! +//! \return The current interrupt status, returned as \b true if active +//! or \b false if not active. +// +//***************************************************************************** +#if defined(GROUP_masterintstatus) || defined(BUILD_ALL) || defined(DOXYGEN) +tBoolean +I2CMasterIntStatus(unsigned long ulBase, tBoolean bMasked) +{ + // + // Check the arguments. + // + ASSERT(ulBase == I2C_MASTER_BASE); + + // + // Return either the interrupt status or the raw interrupt status as + // requested. + // + if(bMasked) + { + return((HWREG(ulBase + I2C_MASTER_O_MIS)) ? true : false); + } + else + { + return((HWREG(ulBase + I2C_MASTER_O_RIS)) ? true : false); + } +} +#endif + +//***************************************************************************** +// +//! Gets the current I2C Slave interrupt status. +//! +//! \param ulBase base address of the I2C Slave module +//! \param bMasked is false if the raw interrupt status is requested and +//! true if the masked interrupt status is requested. +//! +//! This returns the interrupt status for the I2C Slave module. +//! Either the raw interrupt status or the status of interrupts that are +//! allowed to reflect to the processor can be returned. +//! +//! \return The current interrupt status, returned as \b true if active +//! or \b false if not active. +// +//***************************************************************************** +#if defined(GROUP_slaveintstatus) || defined(BUILD_ALL) || defined(DOXYGEN) +tBoolean +I2CSlaveIntStatus(unsigned long ulBase, tBoolean bMasked) +{ + // + // Check the arguments. + // + ASSERT(ulBase == I2C_SLAVE_BASE); + + // + // Return either the interrupt status or the raw interrupt status as + // requested. + // + if(bMasked) + { + return((HWREG(ulBase + I2C_SLAVE_O_MIS)) ? true : false); + } + else + { + return((HWREG(ulBase + I2C_SLAVE_O_RIS)) ? true : false); + } +} +#endif + +//***************************************************************************** +// +//! Clears I2C Master interrupt sources. +//! +//! \param ulBase base address of the I2C Master module +//! +//! The I2C Master interrupt source is cleared, so that it no longer asserts. +//! This must be done in the interrupt handler to keep it from being called +//! again immediately upon exit. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_masterintclear) || defined(BUILD_ALL) || defined(DOXYGEN) +void +I2CMasterIntClear(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == I2C_MASTER_BASE); + + // + // Clear the I2C master interrupt source. + // + HWREG(ulBase + I2C_MASTER_O_MICR) = I2C_MASTER_MICR_IC; + + // + // Workaround for I2C master interrupt clear errata for rev B Stellaris + // devices. For later devices, this write is ignored and therefore + // harmless (other than the slight performance hit). + // + HWREG(ulBase + I2C_MASTER_O_MIS) = I2C_MASTER_MICR_IC; +} +#endif + +//***************************************************************************** +// +//! Clears I2C Slave interrupt sources. +//! +//! \param ulBase base address of the I2C Slave module +//! +//! The I2C Slave interrupt source is cleared, so that it no longer asserts. +//! This must be done in the interrupt handler to keep it from being called +//! again immediately upon exit. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_slaveintclear) || defined(BUILD_ALL) || defined(DOXYGEN) +void +I2CSlaveIntClear(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == I2C_SLAVE_BASE); + + // + // Clear the I2C slave interrupt source. + // + HWREG(ulBase + I2C_SLAVE_O_SICR) = I2C_SLAVE_SICR_IC; +} +#endif + +//***************************************************************************** +// +//! Sets the address that the I2C Master will place on the bus. +//! +//! \param ulBase base address of the I2C Master module +//! \param ucSlaveAddr 7-bit slave address +//! \param bReceive flag indicating the type of communication with the slave +//! +//! This function will set the address that the I2C Master will place on the +//! bus when initiating a transaction. When the parameter \e bReceive is set +//! to \b true, the address will indicate that the I2C Master is initiating +//! a read from the slave; otherwise the address will indicate that the I2C +//! Master is initiating a write to the slave. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_masterslaveaddrset) || defined(BUILD_ALL) || defined(DOXYGEN) +void +I2CMasterSlaveAddrSet(unsigned long ulBase, unsigned char ucSlaveAddr, + tBoolean bReceive) +{ + // + // Check the arguments. + // + ASSERT(ulBase == I2C_MASTER_BASE); + ASSERT(!(ucSlaveAddr & 0x80)); + + // + // Set the address of the slave with which the master will communicate. + // + HWREG(ulBase + I2C_MASTER_O_SA) = (ucSlaveAddr << 1) | bReceive; +} +#endif + +//***************************************************************************** +// +//! Indicates whether or not the I2C Master is busy. +//! +//! \param ulBase base address of the I2C Master module +//! +//! This function returns an indication of whether or not the I2C Master is +//! busy transmitting or receiving data. +//! +//! \return Returns \b true if the I2C Master is busy; otherwise, returns +//! \b false. +// +//***************************************************************************** +#if defined(GROUP_masterbusy) || defined(BUILD_ALL) || defined(DOXYGEN) +tBoolean +I2CMasterBusy(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == I2C_MASTER_BASE); + + // + // Return the busy status. + // + if(HWREG(ulBase + I2C_MASTER_O_CS) & I2C_MASTER_CS_BUSY) + { + return(true); + } + else + { + return(false); + } +} +#endif + +//***************************************************************************** +// +//! Indicates whether or not the I2C bus is busy. +//! +//! \param ulBase base address of the I2C Master module +//! +//! This function returns an indication of whether or not the I2C bus is +//! busy. This function can be used in a multi-master environment to +//! determine if another master is currently using the bus. +//! +//! \return Returns \b true if the I2C bus is busy; otherwise, returns +//! \b false. +// +//***************************************************************************** +#if defined(GROUP_masterbusbusy) || defined(BUILD_ALL) || defined(DOXYGEN) +tBoolean +I2CMasterBusBusy(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == I2C_MASTER_BASE); + + // + // Return the bus busy status. + // + if(HWREG(ulBase + I2C_MASTER_O_CS) & I2C_MASTER_CS_BUS_BUSY) + { + return(true); + } + else + { + return(false); + } +} +#endif + +//***************************************************************************** +// +//! Controls the state of the I2C Master module. +//! +//! \param ulBase base address of the I2C Master module +//! \param ulCmd command to be issued to the I2C Master module +//! +//! This function is used to control the state of the Master module send and +//! receive operations. The parameter \e ucCmd can be one of the following +//! values: +//! +//! - I2C_MASTER_CMD_SINGLE_SEND +//! - I2C_MASTER_CMD_SINGLE_RECEIVE +//! - I2C_MASTER_CMD_BURST_SEND_START +//! - I2C_MASTER_CMD_BURST_SEND_CONT +//! - I2C_MASTER_CMD_BURST_SEND_FINISH +//! - I2C_MASTER_CMD_BURST_SEND_ERROR_STOP +//! - I2C_MASTER_CMD_BURST_RECEIVE_START +//! - I2C_MASTER_CMD_BURST_RECEIVE_CONT +//! - I2C_MASTER_CMD_BURST_RECEIVE_FINISH +//! - I2C_MASTER_CMD_BURST_RECEIVE_ERROR_STOP +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_mastercontrol) || defined(BUILD_ALL) || defined(DOXYGEN) +void +I2CMasterControl(unsigned long ulBase, unsigned long ulCmd) +{ + // + // Check the arguments. + // + ASSERT(ulBase == I2C_MASTER_BASE); + ASSERT((ulCmd == I2C_MASTER_CMD_SINGLE_SEND) || + (ulCmd == I2C_MASTER_CMD_SINGLE_RECEIVE) || + (ulCmd == I2C_MASTER_CMD_BURST_SEND_START) || + (ulCmd == I2C_MASTER_CMD_BURST_SEND_CONT) || + (ulCmd == I2C_MASTER_CMD_BURST_SEND_FINISH) || + (ulCmd == I2C_MASTER_CMD_BURST_SEND_ERROR_STOP) || + (ulCmd == I2C_MASTER_CMD_BURST_RECEIVE_START) || + (ulCmd == I2C_MASTER_CMD_BURST_RECEIVE_CONT) || + (ulCmd == I2C_MASTER_CMD_BURST_RECEIVE_FINISH) || + (ulCmd == I2C_MASTER_CMD_BURST_RECEIVE_ERROR_STOP)); + + // + // Send the command. + // + HWREG(ulBase + I2C_MASTER_O_CS) = ulCmd; +} +#endif + +//***************************************************************************** +// +//! Gets the error status of the I2C Master module. +//! +//! \param ulBase base address of the I2C Master module +//! +//! This function is used to obtain the error status of the Master module +//! send and receive operations. It returns one of the following values: +//! +//! - I2C_MASTER_ERR_NONE +//! - I2C_MASTER_ERR_ADDR_ACK +//! - I2C_MASTER_ERR_DATA_ACK +//! - I2C_MASTER_ERR_ARB_LOST +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_mastererr) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +I2CMasterErr(unsigned long ulBase) +{ + unsigned long ulErr; + + // + // Check the arguments. + // + ASSERT(ulBase == I2C_MASTER_BASE); + + // + // Get the raw error state + // + ulErr = HWREG(ulBase + I2C_MASTER_O_CS); + + // + // If the I2C master is busy, then all the other bit are invalid, and + // don't have an error to report. + // + if(ulErr & I2C_MASTER_CS_BUSY) + { + return(I2C_MASTER_ERR_NONE); + } + + // + // Check for errors. + // + if(ulErr & I2C_MASTER_CS_ERROR) + { + return(ulErr & (I2C_MASTER_CS_ERR_MASK)); + } + else + { + return(I2C_MASTER_ERR_NONE); + } +} +#endif + +//***************************************************************************** +// +//! Transmits a byte from the I2C Master. +//! +//! \param ulBase base address of the I2C Master module +//! \param ucData data to be transmitted from the I2C Master +//! +//! This function will place the supplied data into I2C Master Data Register. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_masterdataput) || defined(BUILD_ALL) || defined(DOXYGEN) +void +I2CMasterDataPut(unsigned long ulBase, unsigned char ucData) +{ + // + // Check the arguments. + // + ASSERT(ulBase == I2C_MASTER_BASE); + + // + // Write the byte. + // + HWREG(ulBase + I2C_MASTER_O_DR) = ucData; +} +#endif + +//***************************************************************************** +// +//! Receives a byte that has been sent to the I2C Master. +//! +//! \param ulBase base address of the I2C Master module +//! +//! This function reads a byte of data from the I2C Master Data Register. +//! +//! \return Returns the byte received from by the I2C Master, cast as an +//! unsigned long. +// +//***************************************************************************** +#if defined(GROUP_masterdataget) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +I2CMasterDataGet(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == I2C_MASTER_BASE); + + // + // Read a byte. + // + return(HWREG(ulBase + I2C_MASTER_O_DR)); +} +#endif + +//***************************************************************************** +// +//! Gets the I2C Slave module status +//! +//! \param ulBase base address of the I2C Slave module +//! +//! This function will return the action requested from a master, if any. The +//! possible values returned are: +//! +//! - I2C_SLAVE_ACT_NONE +//! - I2C_SLAVE_ACT_RREQ +//! - I2C_SLAVE_ACT_TREQ +//! +//! where I2C_SLAVE_ACT_NONE means that no action has been requested of the +//! I2C Slave module, I2C_SLAVE_ACT_RREQ means that an I2C master has sent +//! data to the I2C Slave module, and I2C_SLAVE_ACT_TREQ means that an I2C +//! master has requested that the I2C Slave module send data. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_slavestatus) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +I2CSlaveStatus(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == I2C_SLAVE_BASE); + + // + // Return the slave status. + // + return(HWREG(ulBase + I2C_SLAVE_O_CSR)); +} +#endif + +//***************************************************************************** +// +//! Transmits a byte from the I2C Slave. +//! +//! \param ulBase base address of the I2C Slave module +//! \param ucData data to be transmitted from the I2C Slave +//! +//! This function will place the supplied data into I2C Slave Data Register. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_slavedataput) || defined(BUILD_ALL) || defined(DOXYGEN) +void +I2CSlaveDataPut(unsigned long ulBase, unsigned char ucData) +{ + // + // Check the arguments. + // + ASSERT(ulBase == I2C_SLAVE_BASE); + + // + // Write the byte. + // + HWREG(ulBase + I2C_SLAVE_O_DR) = ucData; +} +#endif + +//***************************************************************************** +// +//! Receives a byte that has been sent to the I2C Slave. +//! +//! \param ulBase base address of the I2C Slave module +//! +//! This function reads a byte of data from the I2C Slave Data Register. +//! +//! \return Returns the byte received from by the I2C Slave, cast as an +//! unsigned long. +// +//***************************************************************************** +#if defined(GROUP_slavedataget) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +I2CSlaveDataGet(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == I2C_SLAVE_BASE); + + // + // Read a byte. + // + return(HWREG(ulBase + I2C_SLAVE_O_DR)); +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/i2c.h b/Demo/CORTEX_LM3S811_GCC/hw_include/i2c.h new file mode 100644 index 000000000..bfe8c8563 --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/i2c.h @@ -0,0 +1,137 @@ +//***************************************************************************** +// +// i2c.h - Prototypes for the I2C Driver. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +#ifndef __I2C_H__ +#define __I2C_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// Defines for the API. +// +//***************************************************************************** +//***************************************************************************** +// +// Interrupt defines. +// +//***************************************************************************** +#define I2C_INT_MASTER 0x00000001 +#define I2C_INT_SLAVE 0x00000002 + +//***************************************************************************** +// +// I2C Master commands. +// +//***************************************************************************** +#define I2C_MASTER_CMD_SINGLE_SEND \ + (I2C_MASTER_CS_STOP | I2C_MASTER_CS_START | I2C_MASTER_CS_RUN) +#define I2C_MASTER_CMD_SINGLE_RECEIVE \ + (I2C_MASTER_CS_STOP | I2C_MASTER_CS_START | I2C_MASTER_CS_RUN) +#define I2C_MASTER_CMD_BURST_SEND_START \ + (I2C_MASTER_CS_START | I2C_MASTER_CS_RUN) +#define I2C_MASTER_CMD_BURST_SEND_CONT \ + (I2C_MASTER_CS_RUN) +#define I2C_MASTER_CMD_BURST_SEND_FINISH \ + (I2C_MASTER_CS_STOP | I2C_MASTER_CS_RUN) +#define I2C_MASTER_CMD_BURST_SEND_ERROR_STOP \ + (I2C_MASTER_CS_STOP) +#define I2C_MASTER_CMD_BURST_RECEIVE_START \ + (I2C_MASTER_CS_ACK | I2C_MASTER_CS_START | I2C_MASTER_CS_RUN) +#define I2C_MASTER_CMD_BURST_RECEIVE_CONT \ + (I2C_MASTER_CS_ACK | I2C_MASTER_CS_RUN) +#define I2C_MASTER_CMD_BURST_RECEIVE_FINISH \ + (I2C_MASTER_CS_STOP | I2C_MASTER_CS_RUN) +#define I2C_MASTER_CMD_BURST_RECEIVE_ERROR_STOP \ + (I2C_MASTER_CS_STOP | I2C_MASTER_CS_RUN) + +//***************************************************************************** +// +// I2C Master error status. +// +//***************************************************************************** +#define I2C_MASTER_ERR_NONE 0 +#define I2C_MASTER_ERR_ADDR_ACK 0x00000004 +#define I2C_MASTER_ERR_DATA_ACK 0x00000008 +#define I2C_MASTER_ERR_ARB_LOST 0x00000010 + +//***************************************************************************** +// +// I2C Slave action requests +// +//***************************************************************************** +#define I2C_SLAVE_ACT_NONE 0 +#define I2C_SLAVE_ACT_RREQ 0x00000001 // Master has sent data +#define I2C_SLAVE_ACT_TREQ 0x00000002 // Master has requested data + +//***************************************************************************** +// Miscellaneous I2C driver definitions. +//***************************************************************************** +#define I2C_MASTER_MAX_RETRIES 1000 // Number of retries + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** +extern void I2CIntRegister(unsigned long ulBase, void(fnHandler)(void)); +extern void I2CIntUnregister(unsigned long ulBase); +extern tBoolean I2CMasterBusBusy(unsigned long ulBase); +extern tBoolean I2CMasterBusy(unsigned long ulBase); +extern void I2CMasterControl(unsigned long ulBase, unsigned long ulCmd); +extern unsigned long I2CMasterDataGet(unsigned long ulBase); +extern void I2CMasterDataPut(unsigned long ulBase, unsigned char ucData); +extern void I2CMasterDisable(unsigned long ulBase); +extern void I2CMasterEnable(unsigned long ulBase); +extern unsigned long I2CMasterErr(unsigned long ulBase); +extern void I2CMasterInit(unsigned long ulBase, tBoolean bFast); +extern void I2CMasterIntClear(unsigned long ulBase); +extern void I2CMasterIntDisable(unsigned long ulBase); +extern void I2CMasterIntEnable(unsigned long ulBase); +extern tBoolean I2CMasterIntStatus(unsigned long ulBase, tBoolean bMasked); +extern void I2CMasterSlaveAddrSet(unsigned long ulBase, + unsigned char ucSlaveAddr, + tBoolean bReceive); +extern unsigned long I2CSlaveDataGet(unsigned long ulBase); +extern void I2CSlaveDataPut(unsigned long ulBase, unsigned char ucData); +extern void I2CSlaveDisable(unsigned long ulBase); +extern void I2CSlaveEnable(unsigned long ulBase); +extern void I2CSlaveInit(unsigned long ulBase, unsigned char ucSlaveAddr); +extern void I2CSlaveIntClear(unsigned long ulBase); +extern void I2CSlaveIntDisable(unsigned long ulBase); +extern void I2CSlaveIntEnable(unsigned long ulBase); +extern tBoolean I2CSlaveIntStatus(unsigned long ulBase, tBoolean bMasked); +extern unsigned long I2CSlaveStatus(unsigned long ulBase); + +#ifdef __cplusplus +} +#endif + +#endif // __I2C_H__ diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/interrupt.c b/Demo/CORTEX_LM3S811_GCC/hw_include/interrupt.c new file mode 100644 index 000000000..7224a05d8 --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/interrupt.c @@ -0,0 +1,552 @@ +//***************************************************************************** +// +// interrupt.c - Driver for the NVIC Interrupt Controller. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +//***************************************************************************** +// +//! \addtogroup interrupt_api +//! @{ +// +//***************************************************************************** + +#include "../hw_ints.h" +#include "../hw_nvic.h" +#include "../hw_types.h" +#include "cpu.h" +#include "debug.h" +#include "interrupt.h" + +//***************************************************************************** +// +// This is a mapping between priority grouping encodings and the number of +// preemption priority bits. +// +//***************************************************************************** +#if defined(GROUP_pulpriority) || defined(BUILD_ALL) +const unsigned long g_pulPriority[] = +{ + NVIC_APINT_PRIGROUP_0_8, NVIC_APINT_PRIGROUP_1_7, NVIC_APINT_PRIGROUP_2_6, + NVIC_APINT_PRIGROUP_3_5, NVIC_APINT_PRIGROUP_4_4, NVIC_APINT_PRIGROUP_5_3, + NVIC_APINT_PRIGROUP_6_2, NVIC_APINT_PRIGROUP_7_1 +}; +#else +extern const unsigned long g_pulPriority[]; +#endif + +//***************************************************************************** +// +// This is a mapping between interrupt number and the register that contains +// the priority encoding for that interrupt. +// +//***************************************************************************** +#if defined(GROUP_pulregs) || defined(BUILD_ALL) +const unsigned long g_pulRegs[12] = +{ + 0, NVIC_SYS_PRI1, NVIC_SYS_PRI2, NVIC_SYS_PRI3, NVIC_PRI0, NVIC_PRI1, + NVIC_PRI2, NVIC_PRI3, NVIC_PRI4, NVIC_PRI5, NVIC_PRI6, NVIC_PRI7 +}; +#else +extern const unsigned long g_pulRegs[12]; +#endif + +//***************************************************************************** +// +//! \internal +//! The default interrupt handler. +//! +//! This is the default interrupt handler for all interrupts. It simply loops +//! forever so that the system state is preserved for observation by a +//! debugger. Since interrupts should be disabled before unregistering the +//! corresponding handler, this should never be called. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_defaulthandler) || defined(BUILD_ALL) +void +IntDefaultHandler(void) +{ + // + // Go into an infinite loop. + // + while(1) + { + } +} +#else +extern void IntDefaultHandler(void); +#endif + +//***************************************************************************** +// +// The processor vector table. +// +// This contains a list of the handlers for the various interrupt sources in +// the system. The layout of this list is defined by the hardware; assertion +// of an interrupt causes the processor to start executing directly at the +// address given in the corresponding location in this list. +// +//***************************************************************************** +#if defined(GROUP_vtable) || defined(BUILD_ALL) +#ifdef ewarm +__no_init void (*g_pfnRAMVectors[NUM_INTERRUPTS])(void) @ "VTABLE"; +#else +__attribute__((section("vtable"))) +void (*g_pfnRAMVectors[NUM_INTERRUPTS])(void); +#endif +#else +extern void (*g_pfnRAMVectors[NUM_INTERRUPTS])(void); +#endif + +//***************************************************************************** +// +//! Enables the processor interrupt. +//! +//! Allows the processor to respond to interrupts. This does not affect the +//! set of interrupts enabled in the interrupt controller; it just gates the +//! single interrupt from the controller to the processor. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_masterenable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +IntMasterEnable(void) +{ + // + // Enable processor interrupts. + // + CPUcpsie(); +} +#endif + +//***************************************************************************** +// +//! Disables the processor interrupt. +//! +//! Prevents the processor from receiving interrupts. This does not affect the +//! set of interrupts enabled in the interrupt controller; it just gates the +//! single interrupt from the controller to the processor. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_masterdisable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +IntMasterDisable(void) +{ + // + // Disable processor interrupts. + // + CPUcpsid(); +} +#endif + +//***************************************************************************** +// +//! Registers a function to be called when an interrupt occurs. +//! +//! \param ulInterrupt specifies the interrupt in question. +//! \param pfnHandler is a pointer to the function to be called. +//! +//! This function is used to specify the handler function to be called when the +//! given interrupt is asserted to the processor. When the interrupt occurs, +//! if it is enabled (via IntEnable()), the handler function will be called in +//! interrupt context. Since the handler function can preempt other code, care +//! must be taken to protect memory or peripherals that are accessed by the +//! handler and other non-handler code. +//! +//! \note The use of this function (directly or indirectly via a peripheral +//! driver interrupt register function) moves the interrupt vector table from +//! flash to SRAM. Therefore, care must be taken when linking the application +//! to ensure that the SRAM vector table is located at the beginning of SRAM; +//! otherwise NVIC will not look in the correct portion of memory for the +//! vector table (it requires the vector table be on a 1 kB memory alignment). +//! Normally, the SRAM vector table is so placed via the use of linker scripts; +//! some tool chains, such as the evaluation version of RV-MDK, do not support +//! linker scripts and therefore will not produce a valid executable. See the +//! discussion of compile-time versus run-time interrupt handler registration +//! in the introduction to this chapter. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_register) || defined(BUILD_ALL) || defined(DOXYGEN) +void +IntRegister(unsigned long ulInterrupt, void (*pfnHandler)(void)) +{ + unsigned long ulIdx; + + // + // Check the arguments. + // + ASSERT(ulInterrupt < NUM_INTERRUPTS); + + // + // Make sure that the RAM vector table is correctly aligned. + // + ASSERT(((unsigned long)g_pfnRAMVectors & 0x000003ff) == 0); + + // + // See if the RAM vector table has been initialized. + // + if(HWREG(NVIC_VTABLE) != (unsigned long)g_pfnRAMVectors) + { + // + // Copy the vector table from the beginning of FLASH to the RAM vector + // table. + // + for(ulIdx = 0; ulIdx < NUM_INTERRUPTS; ulIdx++) + { + g_pfnRAMVectors[ulIdx] = (void (*)(void))HWREG(ulIdx * 4); + } + + // + // Point NVIC at the RAM vector table. + // + HWREG(NVIC_VTABLE) = (unsigned long)g_pfnRAMVectors; + } + + // + // Save the interrupt handler. + // + g_pfnRAMVectors[ulInterrupt] = pfnHandler; +} +#endif + +//***************************************************************************** +// +//! Unregisters the function to be called when an interrupt occurs. +//! +//! \param ulInterrupt specifies the interrupt in question. +//! +//! This function is used to indicate that no handler should be called when the +//! given interrupt is asserted to the processor. The interrupt source will be +//! automatically disabled (via IntDisable()) if necessary. +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_unregister) || defined(BUILD_ALL) || defined(DOXYGEN) +void +IntUnregister(unsigned long ulInterrupt) +{ + // + // Check the arguments. + // + ASSERT(ulInterrupt < NUM_INTERRUPTS); + + // + // Reset the interrupt handler. + // + g_pfnRAMVectors[ulInterrupt] = IntDefaultHandler; +} +#endif + +//***************************************************************************** +// +//! Sets the priority grouping of the interrupt controller. +//! +//! \param ulBits specifies the number of bits of preemptable priority. +//! +//! This function specifies the split between preemptable priority levels and +//! subpriority levels in the interrupt priority specification. The range of +//! the grouping values are dependent upon the hardware implementation; on +//! the Stellaris family it can range from 0 to 3. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_prioritygroupingset) || defined(BUILD_ALL) || \ + defined(DOXYGEN) +void +IntPriorityGroupingSet(unsigned long ulBits) +{ + // + // Check the arguments. + // + ASSERT(ulBits < NUM_PRIORITY_BITS); + + // + // Set the priority grouping. + // + HWREG(NVIC_APINT) = NVIC_APINT_VECTKEY | g_pulPriority[ulBits]; +} +#endif + +//***************************************************************************** +// +//! Gets the priority grouping of the interrupt controller. +//! +//! This function returns the split between preemptable priority levels and +//! subpriority levels in the interrupt priority specification. +//! +//! \return The number of bits of preemptable priority. +// +//***************************************************************************** +#if defined(GROUP_prioritygroupingget) || defined(BUILD_ALL) || \ + defined(DOXYGEN) +unsigned long +IntPriorityGroupingGet(void) +{ + unsigned long ulLoop, ulValue; + + // + // Read the priority grouping. + // + ulValue = HWREG(NVIC_APINT) & NVIC_APINT_PRIGROUP_M; + + // + // Loop through the priority grouping values. + // + for(ulLoop = 0; ulLoop < 8; ulLoop++) + { + // + // Stop looping if this value matches. + // + if(ulValue == g_pulPriority[ulLoop]) + { + break; + } + } + + // + // Return the number of priority bits. + // + return(ulLoop); +} +#endif + +//***************************************************************************** +// +//! Sets the priority of an interrupt. +//! +//! \param ulInterrupt specifies the interrupt in question. +//! \param ucPriority specifies the priority of the interrupt. +//! +//! This function is used to set the priority of an interrupt. When multiple +//! interrupts are asserted simultaneously, the ones with the highest priority +//! are processed before the lower priority interrupts. Smaller numbers +//! correspond to higher interrupt priorities; priority 0 is the highest +//! interrupt priority. +//! +//! The hardware priority mechanism will only look at the upper N bits of the +//! priority level (where N is 3 for the Stellaris family), so any +//! prioritization must be performed in those bits. The remaining bits can be +//! used to sub-prioritize the interrupt sources, and may be used by the +//! hardware priority mechanism on a future part. This arrangement allows +//! priorities to migrate to different NVIC implementations without changing +//! the gross prioritization of the interrupts. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_priorityset) || defined(BUILD_ALL) || defined(DOXYGEN) +void +IntPrioritySet(unsigned long ulInterrupt, unsigned char ucPriority) +{ + unsigned long ulTemp; + + // + // Check the arguments. + // + ASSERT((ulInterrupt >= 4) && (ulInterrupt < NUM_INTERRUPTS)); + + // + // Set the interrupt priority. + // + ulTemp = HWREG(g_pulRegs[ulInterrupt >> 2]); + ulTemp &= ~(0xFF << (8 * (ulInterrupt & 3))); + ulTemp |= ucPriority << (8 * (ulInterrupt & 3)); + HWREG(g_pulRegs[ulInterrupt >> 2]) = ulTemp; +} +#endif + +//***************************************************************************** +// +//! Gets the priority of an interrupt. +//! +//! \param ulInterrupt specifies the interrupt in question. +//! +//! This function gets the priority of an interrupt. See IntPrioritySet() for +//! a definition of the priority value. +//! +//! \return Returns the interrupt priority, or -1 if an invalid interrupt was +//! specified. +// +//***************************************************************************** +#if defined(GROUP_priorityget) || defined(BUILD_ALL) || defined(DOXYGEN) +long +IntPriorityGet(unsigned long ulInterrupt) +{ + // + // Check the arguments. + // + ASSERT((ulInterrupt >= 4) && (ulInterrupt < NUM_INTERRUPTS)); + + // + // Return the interrupt priority. + // + return((HWREG(g_pulRegs[ulInterrupt >> 2]) >> (8 * (ulInterrupt & 3))) & + 0xFF); +} +#endif + +//***************************************************************************** +// +//! Enables an interrupt. +//! +//! \param ulInterrupt specifies the interrupt to be enabled. +//! +//! The specified interrupt is enabled in the interrupt controller. Other +//! enables for the interrupt (such as at the peripheral level) are unaffected +//! by this function. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_enable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +IntEnable(unsigned long ulInterrupt) +{ + // + // Check the arguments. + // + ASSERT(ulInterrupt < NUM_INTERRUPTS); + + // + // Determine the interrupt to enable. + // + if(ulInterrupt == FAULT_MPU) + { + // + // Enable the MemManage interrupt. + // + HWREG(NVIC_SYS_HND_CTRL) |= NVIC_SYS_HND_CTRL_MEM; + } + else if(ulInterrupt == FAULT_BUS) + { + // + // Enable the bus fault interrupt. + // + HWREG(NVIC_SYS_HND_CTRL) |= NVIC_SYS_HND_CTRL_BUS; + } + else if(ulInterrupt == FAULT_USAGE) + { + // + // Enable the usage fault interrupt. + // + HWREG(NVIC_SYS_HND_CTRL) |= NVIC_SYS_HND_CTRL_USAGE; + } + else if(ulInterrupt == FAULT_SYSTICK) + { + // + // Enable the System Tick interrupt. + // + HWREG(NVIC_ST_CTRL) |= NVIC_ST_CTRL_INTEN; + } + else if(ulInterrupt >= INT_GPIOA) + { + // + // Enable the general interrupt. + // + HWREG(NVIC_EN0) = 1 << (ulInterrupt - INT_GPIOA); + } +} +#endif + +//***************************************************************************** +// +//! Disables an interrupt. +//! +//! \param ulInterrupt specifies the interrupt to be disabled. +//! +//! The specified interrupt is disabled in the interrupt controller. Other +//! enables for the interrupt (such as at the peripheral level) are unaffected +//! by this function. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_disable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +IntDisable(unsigned long ulInterrupt) +{ + // + // Check the arguments. + // + ASSERT(ulInterrupt < NUM_INTERRUPTS); + + // + // Determine the interrupt to disable. + // + if(ulInterrupt == FAULT_MPU) + { + // + // Disable the MemManage interrupt. + // + HWREG(NVIC_SYS_HND_CTRL) &= ~(NVIC_SYS_HND_CTRL_MEM); + } + else if(ulInterrupt == FAULT_BUS) + { + // + // Disable the bus fault interrupt. + // + HWREG(NVIC_SYS_HND_CTRL) &= ~(NVIC_SYS_HND_CTRL_BUS); + } + else if(ulInterrupt == FAULT_USAGE) + { + // + // Disable the usage fault interrupt. + // + HWREG(NVIC_SYS_HND_CTRL) &= ~(NVIC_SYS_HND_CTRL_USAGE); + } + else if(ulInterrupt == FAULT_SYSTICK) + { + // + // Disable the System Tick interrupt. + // + HWREG(NVIC_ST_CTRL) &= ~(NVIC_ST_CTRL_INTEN); + } + else if(ulInterrupt >= INT_GPIOA) + { + // + // Disable the general interrupt. + // + HWREG(NVIC_DIS0) = 1 << (ulInterrupt - INT_GPIOA); + } +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/interrupt.h b/Demo/CORTEX_LM3S811_GCC/hw_include/interrupt.h new file mode 100644 index 000000000..37d414dab --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/interrupt.h @@ -0,0 +1,57 @@ +//***************************************************************************** +// +// interrupt.h - Prototypes for the NVIC Interrupt Controller Driver. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +#ifndef __INTERRUPT_H__ +#define __INTERRUPT_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** +extern void IntMasterEnable(void); +extern void IntMasterDisable(void); +extern void IntRegister(unsigned long ulInterrupt, void (*pfnHandler)(void)); +extern void IntUnregister(unsigned long ulInterrupt); +extern void IntPriorityGroupingSet(unsigned long ulBits); +extern unsigned long IntPriorityGroupingGet(void); +extern void IntPrioritySet(unsigned long ulInterrupt, + unsigned char ucPriority); +extern long IntPriorityGet(unsigned long ulInterrupt); +extern void IntEnable(unsigned long ulInterrupt); +extern void IntDisable(unsigned long ulInterrupt); + +#ifdef __cplusplus +} +#endif + +#endif // __INTERRUPT_H__ diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/libdriver.a b/Demo/CORTEX_LM3S811_GCC/hw_include/libdriver.a new file mode 100644 index 0000000000000000000000000000000000000000..85385dcf1a336a1677b09502467c8df716bd416e GIT binary patch literal 246310 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 + { 0x02, 0x01, 0x51, 0x09, 0x06 }, // ? + { 0x32, 0x49, 0x79, 0x41, 0x3e }, // @ + { 0x7e, 0x11, 0x11, 0x11, 0x7e }, // A + { 0x7f, 0x49, 0x49, 0x49, 0x36 }, // B + { 0x3e, 0x41, 0x41, 0x41, 0x22 }, // C + { 0x7f, 0x41, 0x41, 0x22, 0x1c }, // D + { 0x7f, 0x49, 0x49, 0x49, 0x41 }, // E + { 0x7f, 0x09, 0x09, 0x09, 0x01 }, // F + { 0x3e, 0x41, 0x49, 0x49, 0x7a }, // G + { 0x7f, 0x08, 0x08, 0x08, 0x7f }, // H + { 0x00, 0x41, 0x7f, 0x41, 0x00 }, // I + { 0x20, 0x40, 0x41, 0x3f, 0x01 }, // J + { 0x7f, 0x08, 0x14, 0x22, 0x41 }, // K + { 0x7f, 0x40, 0x40, 0x40, 0x40 }, // L + { 0x7f, 0x02, 0x0c, 0x02, 0x7f }, // M + { 0x7f, 0x04, 0x08, 0x10, 0x7f }, // N + { 0x3e, 0x41, 0x41, 0x41, 0x3e }, // O + { 0x7f, 0x09, 0x09, 0x09, 0x06 }, // P + { 0x3e, 0x41, 0x51, 0x21, 0x5e }, // Q + { 0x7f, 0x09, 0x19, 0x29, 0x46 }, // R + { 0x46, 0x49, 0x49, 0x49, 0x31 }, // S + { 0x01, 0x01, 0x7f, 0x01, 0x01 }, // T + { 0x3f, 0x40, 0x40, 0x40, 0x3f }, // U + { 0x1f, 0x20, 0x40, 0x20, 0x1f }, // V + { 0x3f, 0x40, 0x38, 0x40, 0x3f }, // W + { 0x63, 0x14, 0x08, 0x14, 0x63 }, // X + { 0x07, 0x08, 0x70, 0x08, 0x07 }, // Y + { 0x61, 0x51, 0x49, 0x45, 0x43 }, // Z + { 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 }, // a + { 0x7f, 0x48, 0x44, 0x44, 0x38 }, // b + { 0x38, 0x44, 0x44, 0x44, 0x20 }, // c + { 0x38, 0x44, 0x44, 0x48, 0x7f }, // d + { 0x38, 0x54, 0x54, 0x54, 0x18 }, // e + { 0x08, 0x7e, 0x09, 0x01, 0x02 }, // f + { 0x0c, 0x52, 0x52, 0x52, 0x3e }, // g + { 0x7f, 0x08, 0x04, 0x04, 0x78 }, // h + { 0x00, 0x44, 0x7d, 0x40, 0x00 }, // i + { 0x20, 0x40, 0x44, 0x3d, 0x00 }, // j + { 0x7f, 0x10, 0x28, 0x44, 0x00 }, // k + { 0x00, 0x41, 0x7f, 0x40, 0x00 }, // l + { 0x7c, 0x04, 0x18, 0x04, 0x78 }, // m + { 0x7c, 0x08, 0x04, 0x04, 0x78 }, // n + { 0x38, 0x44, 0x44, 0x44, 0x38 }, // o + { 0x7c, 0x14, 0x14, 0x14, 0x08 }, // p + { 0x08, 0x14, 0x14, 0x18, 0x7c }, // q + { 0x7c, 0x08, 0x04, 0x04, 0x08 }, // r + { 0x48, 0x54, 0x54, 0x54, 0x20 }, // s + { 0x04, 0x3f, 0x44, 0x40, 0x20 }, // t + { 0x3c, 0x40, 0x40, 0x20, 0x7c }, // u + { 0x1c, 0x20, 0x40, 0x20, 0x1c }, // v + { 0x3c, 0x40, 0x30, 0x40, 0x3c }, // w + { 0x44, 0x28, 0x10, 0x28, 0x44 }, // x + { 0x0c, 0x50, 0x50, 0x50, 0x3c }, // y + { 0x44, 0x64, 0x54, 0x4c, 0x44 }, // z + { 0x00, 0x08, 0x36, 0x41, 0x00 }, // { + { 0x00, 0x00, 0x7f, 0x00, 0x00 }, // | + { 0x00, 0x41, 0x36, 0x08, 0x00 }, // } + { 0x02, 0x01, 0x02, 0x04, 0x02 }, // ~ +}; + +//***************************************************************************** +// +// The sequence of commands used to initialize the SSD0303 controller. Each +// command is described as follows: there is a byte specifying the number of +// bytes in the I2C transfer, followed by that many bytes of command data. +// +//***************************************************************************** +static const unsigned char g_pucOSRAMInit[] = +{ + // + // Turn off the panel + // + 0x04, 0x80, 0xae, 0x80, 0xe3, + + // + // Set lower column address + // + 0x04, 0x80, 0x04, 0x80, 0xe3, + + // + // Set higher column address + // + 0x04, 0x80, 0x12, 0x80, 0xe3, + + // + // Set contrast control register + // + 0x06, 0x80, 0x81, 0x80, 0x2b, 0x80, 0xe3, + + // + // Set segment re-map + // + 0x04, 0x80, 0xa1, 0x80, 0xe3, + + // + // Set display start line + // + 0x04, 0x80, 0x40, 0x80, 0xe3, + + // + // Set display offset + // + 0x06, 0x80, 0xd3, 0x80, 0x00, 0x80, 0xe3, + + // + // Set multiplex ratio + // + 0x06, 0x80, 0xa8, 0x80, 0x0f, 0x80, 0xe3, + + // + // Set the display to normal mode + // + 0x04, 0x80, 0xa4, 0x80, 0xe3, + + // + // Non-inverted display + // + 0x04, 0x80, 0xa6, 0x80, 0xe3, + + // + // Set the page address + // + 0x04, 0x80, 0xb0, 0x80, 0xe3, + + // + // Set COM output scan direction + // + 0x04, 0x80, 0xc8, 0x80, 0xe3, + + // + // Set display clock divide ratio/oscillator frequency + // + 0x06, 0x80, 0xd5, 0x80, 0x72, 0x80, 0xe3, + + // + // Enable mono mode + // + 0x06, 0x80, 0xd8, 0x80, 0x00, 0x80, 0xe3, + + // + // Set pre-charge period + // + 0x06, 0x80, 0xd9, 0x80, 0x22, 0x80, 0xe3, + + // + // Set COM pins hardware configuration + // + 0x06, 0x80, 0xda, 0x80, 0x12, 0x80, 0xe3, + + // + // Set VCOM deslect level + // + 0x06, 0x80, 0xdb, 0x80, 0x0f, 0x80, 0xe3, + + // + // Set DC-DC on + // + 0x06, 0x80, 0xad, 0x80, 0x8b, 0x80, 0xe3, + + // + // Turn on the panel + // + 0x04, 0x80, 0xaf, 0x80, 0xe3, +}; + +//***************************************************************************** +// +// The inter-byte delay required by the SSD0303 OLED controller. +// +//***************************************************************************** +static unsigned long g_ulDelay; + +//***************************************************************************** +// +//! \internal +//! +//! Provide a small delay. +//! +//! \param ulCount is the number of delay loop iterations to perform. +//! +//! Since the SSD0303 controller needs a delay between bytes written to it over +//! the I2C bus, this function provides a means of generating that delay. It +//! is written in assembly to keep the delay consistent across tool chains, +//! avoiding the need to tune the delay based on the tool chain in use. +//! +//! \return None. +// +//***************************************************************************** +#if defined(ewarm) +static void +OSRAMDelay(unsigned long ulCount) +{ + __asm(" subs r0, #1\n" + " bne OSRAMDelay\n" + " bx lr"); +} +#endif +#if defined(gcc) +static void __attribute__((naked)) +OSRAMDelay(unsigned long ulCount) +{ + __asm(" subs r0, #1\n" + " bne OSRAMDelay\n" + " bx lr"); +} +#endif +#if defined(rvmdk) || defined(__ARMCC_VERSION) +__asm void +OSRAMDelay(unsigned long ulCount) +{ + subs r0, #1; + bne OSRAMDelay; + bx lr; +} +#endif + +//***************************************************************************** +// +//! \internal +//! +//! Start a transfer to the SSD0303 controller. +//! +//! \param ucChar is the first byte to be written to the controller. +//! +//! This function will start a transfer to the SSD0303 controller via the I2C +//! bus. +//! +//! The data is written in a polled fashion; this function will not return +//! until the byte has been written to the controller. +//! +//! \return None. +// +//***************************************************************************** +static void +OSRAMWriteFirst(unsigned char ucChar) +{ + // + // Set the slave address. + // + I2CMasterSlaveAddrSet(I2C_MASTER_BASE, SSD0303_ADDR, false); + + // + // Write the first byte to the controller. + // + I2CMasterDataPut(I2C_MASTER_BASE, ucChar); + + // + // Start the transfer. + // + I2CMasterControl(I2C_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_START); +} + +//***************************************************************************** +// +//! \internal +//! +//! Write a byte to the SSD0303 controller. +//! +//! \param ucChar is the byte to be transmitted to the controller. +//! +//! This function continues a transfer to the SSD0303 controller by writing +//! another byte over the I2C bus. This must only be called after calling +//! OSRAMWriteFirst(), but before calling OSRAMWriteFinal(). +//! +//! The data is written in a polled faashion; this function will not return +//! until the byte has been written to the controller. +//! +//! \return None. +// +//***************************************************************************** +static void +OSRAMWriteByte(unsigned char ucChar) +{ + // + // Wait until the current byte has been transferred. + // + while(I2CMasterIntStatus(I2C_MASTER_BASE, false) == 0) + { + } + + // + // Provide the required inter-byte delay. + // + OSRAMDelay(g_ulDelay); + + // + // Write the next byte to the controller. + // + I2CMasterDataPut(I2C_MASTER_BASE, ucChar); + + // + // Continue the transfer. + // + I2CMasterControl(I2C_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_CONT); +} + +//***************************************************************************** +// +//! \internal +//! +//! Write a sequence of bytes to the SSD0303 controller. +//! +//! This function continues a transfer to the SSD0303 controller by writing a +//! sequence of bytes over the I2C bus. This must only be called after calling +//! OSRAMWriteFirst(), but before calling OSRAMWriteFinal(). +//! +//! The data is written in a polled fashion; this function will not return +//! until the entire byte sequence has been written to the controller. +//! +//! \return None. +// +//***************************************************************************** +static void +OSRAMWriteArray(const unsigned char *pucBuffer, unsigned long ulCount) +{ + // + // Loop while there are more bytes left to be transferred. + // + while(ulCount != 0) + { + // + // Wait until the current byte has been transferred. + // + while(I2CMasterIntStatus(I2C_MASTER_BASE, false) == 0) + { + } + + // + // Provide the required inter-byte delay. + // + OSRAMDelay(g_ulDelay); + + // + // Write the next byte to the controller. + // + I2CMasterDataPut(I2C_MASTER_BASE, *pucBuffer++); + ulCount--; + + // + // Continue the transfer. + // + I2CMasterControl(I2C_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_CONT); + } +} + +//***************************************************************************** +// +//! \internal +//! +//! Finish a transfer to the SSD0303 controller. +//! +//! \param ucChar is the final byte to be written to the controller. +//! +//! This function will finish a transfer to the SSD0303 controller via the I2C +//! bus. This must only be called after calling OSRAMWriteFirst(). +//! +//! The data is written in a polled fashion; this function will not return +//! until the byte has been written to the controller. +//! +//! \return None. +// +//***************************************************************************** +static void +OSRAMWriteFinal(unsigned char ucChar) +{ + // + // Wait until the current byte has been transferred. + // + while(I2CMasterIntStatus(I2C_MASTER_BASE, false) == 0) + { + } + + // + // Provide the required inter-byte delay. + // + OSRAMDelay(g_ulDelay); + + // + // Write the final byte to the controller. + // + I2CMasterDataPut(I2C_MASTER_BASE, ucChar); + + // + // Finish the transfer. + // + I2CMasterControl(I2C_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH); + + // + // Wait until the final byte has been transferred. + // + while(I2CMasterIntStatus(I2C_MASTER_BASE, false) == 0) + { + } + + // + // Provide the required inter-byte delay. + // + OSRAMDelay(g_ulDelay); +} + +//***************************************************************************** +// +//! Clears the OLED display. +//! +//! This function will clear the display. All pixels in the display will be +//! turned off. +//! +//! This function is contained in osram96x16.c, with +//! osram96x16.h containing the API definition for use by +//! applications. +//! +//! \return None. +// +//***************************************************************************** +void +OSRAMClear(void) +{ + static const unsigned char pucRow1[] = + { + 0xb0, 0x80, 0x04, 0x80, 0x12, 0x40 + }; + static const unsigned char pucRow2[] = + { + 0xb1, 0x80, 0x04, 0x80, 0x12, 0x40 + }; + unsigned long ulIdx; + + // + // Move the display cursor to the first column of the first row. + // + OSRAMWriteFirst(0x80); + OSRAMWriteArray(pucRow1, sizeof(pucRow1)); + + // + // Fill this row with zeros. + // + for(ulIdx = 0; ulIdx < 95; ulIdx++) + { + OSRAMWriteByte(0x00); + } + OSRAMWriteFinal(0x00); + + // + // Move the display cursor to the first column of the second row. + // + OSRAMWriteFirst(0x80); + OSRAMWriteArray(pucRow2, sizeof(pucRow2)); + + // + // Fill this row with zeros. + // + for(ulIdx = 0; ulIdx < 95; ulIdx++) + { + OSRAMWriteByte(0x00); + } + OSRAMWriteFinal(0x00); +} + +//***************************************************************************** +// +//! Displays a string on the OLED display. +//! +//! \param pcStr is a pointer to the string to display. +//! \param ulX is the horizontal position to display the string, specified in +//! columns from the left edge of the display. +//! \param ulY is the vertical position to display the string, specified in +//! eight scan line blocks from the top of the display (i.e. only 0 and 1 are +//! valid). +//! +//! This function will draw a string on the display. Only the ASCII characters +//! between 32 (space) and 126 (tilde) are supported; other characters will +//! result in random data being draw on the display (based on whatever appears +//! before/after the font in memory). The font is mono-spaced, so characters +//! such as "i" and "l" have more white space around them than characters such +//! as "m" or "w". +//! +//! If the drawing of the string reaches the right edge of the display, no more +//! characters will be drawn. Therefore, special care is not required to avoid +//! supplying a string that is "too long" to display. +//! +//! This function is contained in osram96x16.c, with +//! osram96x16.h containing the API definition for use by +//! applications. +//! +//! \return None. +// +//***************************************************************************** +void +OSRAMStringDraw(const char *pcStr, unsigned long ulX, unsigned long ulY) +{ + // + // Check the arguments. + // + ASSERT(ulX < 96); + ASSERT(ulY < 2); + + // + // Move the display cursor to the requested position on the display. + // + OSRAMWriteFirst(0x80); + OSRAMWriteByte((ulY == 0) ? 0xb0 : 0xb1); + OSRAMWriteByte(0x80); + OSRAMWriteByte((ulX + 36) & 0x0f); + OSRAMWriteByte(0x80); + OSRAMWriteByte(0x10 | (((ulX + 36) >> 4) & 0x0f)); + OSRAMWriteByte(0x40); + + // + // Loop while there are more characters in the string. + // + while(*pcStr != 0) + { + // + // See if there is enough space on the display for this entire + // character. + // + if(ulX <= 90) + { + // + // Write the contents of this character to the display. + // + OSRAMWriteArray(g_pucFont[*pcStr - ' '], 5); + + // + // See if this is the last character to display (either because the + // right edge has been reached or because there are no more + // characters). + // + if((ulX == 90) || (pcStr[1] == 0)) + { + // + // Write the final column of the display. + // + OSRAMWriteFinal(0x00); + + // + // The string has been displayed. + // + return; + } + + // + // Write the inter-character padding column. + // + OSRAMWriteByte(0x00); + } + else + { + // + // Write the portion of the character that will fit onto the + // display. + // + OSRAMWriteArray(g_pucFont[*pcStr - ' '], 95 - ulX); + OSRAMWriteFinal(g_pucFont[*pcStr - ' '][95 - ulX]); + + // + // The string has been displayed. + // + return; + } + + // + // Advance to the next character. + // + pcStr++; + + // + // Increment the X coordinate by the six columns that were just + // written. + // + ulX += 6; + } +} + +//***************************************************************************** +// +//! Displays an image on the OLED display. +//! +//! \param pucImage is a pointer to the image data. +//! \param ulX is the horizontal position to display this image, specified in +//! columns from the left edge of the display. +//! \param ulY is the vertical position to display this image, specified in +//! eight scan line blocks from the top of the display (i.e. only 0 and 1 are +//! valid). +//! \param ulWidth is the width of the image, specified in columns. +//! \param ulHeight is the height of the image, specified in eight row blocks +//! (i.e. only 1 and 2 are valid). +//! +//! This function will display a bitmap graphic on the display. The image to +//! be displayed must be a multiple of eight scan lines high (i.e. one row) and +//! will be drawn at a vertical position that is a multiple of eight scan lines +//! (i.e. scan line zero or scan line eight, corresponding to row zero or row +//! one). +//! +//! The image data is organized with the first row of image data appearing left +//! to right, followed immediately by the second row of image data. Each byte +//! contains the data for the eight scan lines of the column, with the top scan +//! line being in the least significant bit of the byte and the bottom scan +//! line being in the most significant bit of the byte. +//! +//! For example, an image four columns wide and sixteen scan lines tall would +//! be arranged as follows (showing how the eight bytes of the image would +//! appear on the display): +//! +//! \verbatim +//! +-------+ +-------+ +-------+ +-------+ +//! | | 0 | | | 0 | | | 0 | | | 0 | +//! | B | 1 | | B | 1 | | B | 1 | | B | 1 | +//! | y | 2 | | y | 2 | | y | 2 | | y | 2 | +//! | t | 3 | | t | 3 | | t | 3 | | t | 3 | +//! | e | 4 | | e | 4 | | e | 4 | | e | 4 | +//! | | 5 | | | 5 | | | 5 | | | 5 | +//! | 0 | 6 | | 1 | 6 | | 2 | 6 | | 3 | 6 | +//! | | 7 | | | 7 | | | 7 | | | 7 | +//! +-------+ +-------+ +-------+ +-------+ +//! +//! +-------+ +-------+ +-------+ +-------+ +//! | | 0 | | | 0 | | | 0 | | | 0 | +//! | B | 1 | | B | 1 | | B | 1 | | B | 1 | +//! | y | 2 | | y | 2 | | y | 2 | | y | 2 | +//! | t | 3 | | t | 3 | | t | 3 | | t | 3 | +//! | e | 4 | | e | 4 | | e | 4 | | e | 4 | +//! | | 5 | | | 5 | | | 5 | | | 5 | +//! | 4 | 6 | | 5 | 6 | | 6 | 6 | | 7 | 6 | +//! | | 7 | | | 7 | | | 7 | | | 7 | +//! +-------+ +-------+ +-------+ +-------+ +//! \endverbatim +//! +//! This function is contained in osram96x16.c, with +//! osram96x16.h containing the API definition for use by +//! applications. +//! +//! \return None. +// +//***************************************************************************** +void +OSRAMImageDraw(const unsigned char *pucImage, unsigned long ulX, + unsigned long ulY, unsigned long ulWidth, + unsigned long ulHeight) +{ + // + // Check the arguments. + // + ASSERT(ulX < 96); + ASSERT(ulY < 2); + ASSERT((ulX + ulWidth) <= 96); + ASSERT((ulY + ulHeight) <= 2); + + // + // The first 36 columns of the LCD buffer are not displayed, so increment + // the X coorddinate by 36 to account for the non-displayed frame buffer + // memory. + // + ulX += 36; + + // + // Loop while there are more rows to display. + // + while(ulHeight--) + { + // + // Write the starting address within this row. + // + OSRAMWriteFirst(0x80); + OSRAMWriteByte((ulY == 0) ? 0xb0 : 0xb1); + OSRAMWriteByte(0x80); + OSRAMWriteByte(ulX & 0x0f); + OSRAMWriteByte(0x80); + OSRAMWriteByte(0x10 | ((ulX >> 4) & 0x0f)); + OSRAMWriteByte(0x40); + + // + // Write this row of image data. + // + OSRAMWriteArray(pucImage, ulWidth - 1); + OSRAMWriteFinal(pucImage[ulWidth - 1]); + + // + // Advance to the next row of the image. + // + pucImage += ulWidth; + ulY++; + } +} + +//***************************************************************************** +// +//! Initialize the OLED display. +//! +//! \param bFast is a boolean that is \e true if the I2C interface should be +//! run at 400 kbps and \e false if it should be run at 100 kbps. +//! +//! This function initializes the I2C interface to the OLED display and +//! configures the SSD0303 controller on the panel. +//! +//! This function is contained in osram96x16.c, with +//! osram96x16.h containing the API definition for use by +//! applications. +//! +//! \return None. +// +//***************************************************************************** +void +OSRAMInit(tBoolean bFast) +{ + unsigned long ulIdx; + + // + // Enable the I2C and GPIO port B blocks as they are needed by this driver. + // + SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C); + SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); + + // + // Configure the I2C SCL and SDA pins for I2C operation. + // + GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_2 | GPIO_PIN_3); + + // + // Initialize the I2C master. + // + I2CMasterInit(I2C_MASTER_BASE, bFast); + + // + // Compute the inter-byte delay for the SSD0303 controller. This delay is + // dependent upon the I2C bus clock rate; the slower the clock the longer + // the delay required. + // + // The derivation of this formula is based on a measured delay of + // OSRAMDelay(1700) for a 100 kHz I2C bus with the CPU running at 50 MHz + // (referred to as C). To scale this to the delay for a different CPU + // speed (since this is just a CPU-based delay loop) is: + // + // f(CPU) + // C * ---------- + // 50,000,000 + // + // To then scale this to the actual I2C rate (since it won't always be + // precisely 100 kHz): + // + // f(CPU) 100,000 + // C * ---------- * ------- + // 50,000,000 f(I2C) + // + // This equation will give the inter-byte delay required for any + // configuration of the I2C master. But, as arranged it is impossible to + // directly compute in 32-bit arithmetic (without loosing a lot of + // accuracy). So, the equation is simplified. + // + // Since f(I2C) is generated by dividing down from f(CPU), replace it with + // the equivalent (where TPR is the value programmed into the Master Timer + // Period Register of the I2C master, with the 1 added back): + // + // 100,000 + // f(CPU) ------- + // C * ---------- * f(CPU) + // 50,000,000 ------------ + // 2 * 10 * TPR + // + // Inverting the dividend in the last term: + // + // f(CPU) 100,000 * 2 * 10 * TPR + // C * ---------- * ---------------------- + // 50,000,000 f(CPU) + // + // The f(CPU) now cancels out. + // + // 100,000 * 2 * 10 * TPR + // C * ---------------------- + // 50,000,000 + // + // Since there are no clock frequencies left in the equation, this equation + // also works for 400 kHz bus operation as well, since the 100,000 in the + // numerator becomes 400,000 but C is 1/4, which cancel out each other. + // Reducing the constants gives: + // + // TPR TPR TPR + // C * --- = 1700 * --- = 340 * --- = 68 * TPR + // 25 25 5 + // + // Note that the constant C is actually a bit larger than it needs to be in + // order to provide some safety margin. + // + g_ulDelay = 68 * (HWREG(I2C_MASTER_BASE + I2C_MASTER_O_TPR) + 1); + + // + // Initialize the SSD0303 controller. Loop through the initialization + // sequence doing a single I2C transfer for each command. + // + for(ulIdx = 0; ulIdx < sizeof(g_pucOSRAMInit); + ulIdx += g_pucOSRAMInit[ulIdx] + 1) + { + // + // Send this command. + // + OSRAMWriteFirst(g_pucOSRAMInit[ulIdx + 1]); + OSRAMWriteArray(g_pucOSRAMInit + ulIdx + 2, g_pucOSRAMInit[ulIdx] - 2); + OSRAMWriteFinal(g_pucOSRAMInit[ulIdx + g_pucOSRAMInit[ulIdx]]); + } + + // + // Clear the frame buffer. + // + OSRAMClear(); +} + +//***************************************************************************** +// +//! Turns on the OLED display. +//! +//! This function will turn on the OLED display, causing it to display the +//! contents of its internal frame buffer. +//! +//! This function is contained in osram96x16.c, with +//! osram96x16.h containing the API definition for use by +//! applications. +//! +//! \return None. +// +//***************************************************************************** +void +OSRAMDisplayOn(void) +{ + unsigned long ulIdx; + + // + // Re-initialize the SSD0303 controller. Loop through the initialization + // sequence doing a single I2C transfer for each command. + // + for(ulIdx = 0; ulIdx < sizeof(g_pucOSRAMInit); + ulIdx += g_pucOSRAMInit[ulIdx] + 1) + { + // + // Send this command. + // + OSRAMWriteFirst(g_pucOSRAMInit[ulIdx + 1]); + OSRAMWriteArray(g_pucOSRAMInit + ulIdx + 2, g_pucOSRAMInit[ulIdx] - 2); + OSRAMWriteFinal(g_pucOSRAMInit[ulIdx + g_pucOSRAMInit[ulIdx]]); + } +} + +//***************************************************************************** +// +//! Turns off the OLED display. +//! +//! This function will turn off the OLED display. This will stop the scanning +//! of the panel and turn off the on-chip DC-DC converter, preventing damage to +//! the panel due to burn-in (it has similar characters to a CRT in this +//! respect). +//! +//! This function is contained in osram96x16.c, with +//! osram96x16.h containing the API definition for use by +//! applications. +//! +//! \return None. +// +//***************************************************************************** +void +OSRAMDisplayOff(void) +{ + // + // Turn off the DC-DC converter and the display. + // + OSRAMWriteFirst(0x80); + OSRAMWriteByte(0xae); + OSRAMWriteByte(0x80); + OSRAMWriteByte(0xad); + OSRAMWriteByte(0x80); + OSRAMWriteFinal(0x8a); +} + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/osram96x16.h b/Demo/CORTEX_LM3S811_GCC/hw_include/osram96x16.h new file mode 100644 index 000000000..0c9cd3692 --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/osram96x16.h @@ -0,0 +1,47 @@ +//***************************************************************************** +// +// osram96x16.h - Prototypes for the driver for the OSRAM 96x16 graphical OLED +// display. +// +// Copyright (c) 2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +#ifndef __OSRAM96X16_H__ +#define __OSRAM96X16_H__ + +//***************************************************************************** +// +// Prototypes for the driver APIs. +// +//***************************************************************************** +extern void OSRAMClear(void); +extern void OSRAMStringDraw(const char *pcStr, unsigned long ulX, + unsigned long ulY); +extern void OSRAMImageDraw(const unsigned char *pucImage, unsigned long ulX, + unsigned long ulY, unsigned long ulWidth, + unsigned long ulHeight); +extern void OSRAMInit(tBoolean bFast); +extern void OSRAMDisplayOn(void); +extern void OSRAMDisplayOff(void); + +#endif // __OSRAM96X16_H__ diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/pwm.c b/Demo/CORTEX_LM3S811_GCC/hw_include/pwm.c new file mode 100644 index 000000000..6697566ea --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/pwm.c @@ -0,0 +1,1291 @@ +//***************************************************************************** +// +// pwm.c - API for the PWM modules +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +//***************************************************************************** +// +//! \addtogroup pwm_api +//! @{ +// +//***************************************************************************** + +#include "../hw_ints.h" +#include "../hw_memmap.h" +#include "../hw_pwm.h" +#include "../hw_types.h" +#include "debug.h" +#include "interrupt.h" +#include "pwm.h" + +//***************************************************************************** +// +// Misc macros for manipulating the encoded generator and output defines used +// by the API. +// +//***************************************************************************** +#define PWM_GEN_BADDR(_mod_, _gen_) \ + ((_mod_) + (_gen_)) +#define PWM_OUT_BADDR(_mod_, _out_) \ + ((_mod_) + ((_out_) & 0xFFFFFFC0)) +#define PWM_IS_OUTPUT_ODD(_out_) \ + ((_out_) & 0x00000001) + +//***************************************************************************** +// +//! Configures a PWM generator. +//! +//! \param ulBase is the base address of the PWM module. +//! \param ulGen is the PWM generator to configure. Must be one of +//! \b PWM_GEN_0, \b PWM_GEN_1, or \b PWM_GEN_2. +//! \param ulConfig is the configuration for the PWM generator. +//! +//! This function is used to set the mode of operation for a PWM generator. +//! The counting mode, synchronization mode, and debug behavior are all +//! configured. After configuration, the generator is left in the disabled +//! state. +//! +//! A PWM generator can count in two different modes: count down mode or count +//! up/down mode. In count down mode, it will count from a value down to zero, +//! and then reset to the preset value. This will produce left-aligned PWM +//! signals (i.e. the rising edge of the two PWM signals produced by the +//! generator will occur at the same time). In count up/down mode, it will +//! count up from zero to the preset value, count back down to zero, and then +//! repeat the process. This will produce center-aligned PWM signals (i.e. the +//! middle of the high/low period of the PWM signals produced by the generator +//! will occur at the same time). +//! +//! When the PWM generator parameters (period and pulse width) are modified, +//! their affect on the output PWM signals can be delayed. In synchronous +//! mode, the parameter updates are not applied until a synchronization event +//! occurs. This allows multiple parameters to be modified and take affect +//! simultaneously, instead of one at a time. Additionally, parameters to +//! multiple PWM generators in synchronous mode can be updated simultaneously, +//! allowing them to be treated as if they were a unified generator. In +//! non-synchronous mode, the parameter updates are not delayed until a +//! synchronization event. In either mode, the parameter updates only occur +//! when the counter is at zero to help prevent oddly formed PWM signals during +//! the update (i.e. a PWM pulse that is too short or too long). +//! +//! The PWM generator can either pause or continue running when the processor +//! is stopped via the debugger. If configured to pause, it will continue to +//! count until it reaches zero, at which point it will pause until the +//! processor is restarted. If configured to continue running, it will keep +//! counting as if nothing had happened. +//! +//! The \b ulConfig parameter contains the desired configuration. It is the +//! logical OR of the following: \b PWM_GEN_MODE_DOWN or +//! \b PWM_GEN_MODE_UP_DOWN to specify the counting mode, \b PWM_GEN_MODE_SYNC +//! or \b PWM_GEN_MODE_NO_SYNC to specify the synchronization mode, and +//! \b PWM_GEN_MODE_DBG_RUN or \b PWM_GEN_MODE_DBG_STOP to specify the debug +//! behavior. +//! +//! \note Changes to the counter mode will affect the period of the PWM signals +//! produced. PWMGenPeriodSet() and PWMPulseWidthSet() should be called after +//! any changes to the counter mode of a generator. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_genconfigure) || defined(BUILD_ALL) || defined(DOXYGEN) +void +PWMGenConfigure(unsigned long ulBase, unsigned long ulGen, + unsigned long ulConfig) +{ + // + // Check the arguments. + // + ASSERT(ulBase == PWM_BASE); + ASSERT((ulGen == PWM_GEN_0) || (ulGen == PWM_GEN_1) || + (ulGen == PWM_GEN_2)); + + // + // Compute the generator's base address. + // + ulGen = PWM_GEN_BADDR(ulBase, ulGen); + + // + // Change the global configuration of the generator. + // + HWREG(ulGen + PWM_O_X_CTL) = ((HWREG(ulGen + PWM_O_X_CTL) & + ~(PWM_X_CTL_MODE | PWM_X_CTL_DEBUG | + PWM_X_CTL_LOADUPD | PWM_X_CTL_CMPAUPD | + PWM_X_CTL_CMPBUPD)) | ulConfig); + + // + // Set the individual PWM generator controls. + // + if(ulConfig & PWM_X_CTL_MODE) + { + // + // In up/down count mode, set the signal high on up count comparison + // and low on down count comparison (i.e. center align the signals). + // + HWREG(ulGen + PWM_O_X_GENA) = ((PWM_GEN_ACT_ONE << + PWM_GEN_ACT_A_UP_SHIFT) | + (PWM_GEN_ACT_ZERO << + PWM_GEN_ACT_A_DN_SHIFT)); + HWREG(ulGen + PWM_O_X_GENB) = ((PWM_GEN_ACT_ONE << + PWM_GEN_ACT_B_UP_SHIFT) | + (PWM_GEN_ACT_ZERO << + PWM_GEN_ACT_B_DN_SHIFT)); + } + else + { + // + // In down count mode, set the signal high on load and low on count + // comparison (i.e. left align the signals). + // + HWREG(ulGen + PWM_O_X_GENA) = ((PWM_GEN_ACT_ONE << + PWM_GEN_ACT_LOAD_SHIFT) | + (PWM_GEN_ACT_ZERO << + PWM_GEN_ACT_A_DN_SHIFT)); + HWREG(ulGen + PWM_O_X_GENB) = ((PWM_GEN_ACT_ONE << + PWM_GEN_ACT_LOAD_SHIFT) | + (PWM_GEN_ACT_ZERO << + PWM_GEN_ACT_B_DN_SHIFT)); + } +} +#endif + +//***************************************************************************** +// +//! Set the period of a PWM generator. +//! +//! \param ulBase is the base address of the PWM module. +//! \param ulGen is the PWM generator to be modified. Must be one of +//! \b PWM_GEN_0, \b PWM_GEN_1, or \b PWM_GEN_2. +//! \param ulPeriod specifies the period of PWM generator output, measured +//! in clock ticks. +//! +//! This function sets the period of the specified PWM generator block, where +//! the period of the generator block is defined as the number of \b PWM +//! clock ticks between pulses on the generator block \b zero signal. +//! +//! \note Any subsequent calls made to this function before an update occurs +//! will cause the previous values to be overwritten. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_genperiodset) || defined(BUILD_ALL) || defined(DOXYGEN) +void +PWMGenPeriodSet(unsigned long ulBase, unsigned long ulGen, + unsigned long ulPeriod) +{ + // + // Check the arguments. + // + ASSERT(ulBase == PWM_BASE); + ASSERT((ulGen == PWM_GEN_0) || (ulGen == PWM_GEN_1) || + (ulGen == PWM_GEN_2)); + + // + // Compute the generator's base address. + // + ulGen = PWM_GEN_BADDR(ulBase, ulGen); + + // + // Set the reload register based on the mode. + // + if(HWREG(ulGen + PWM_O_X_CTL) & PWM_X_CTL_MODE) + { + // + // In up/down count mode, set the reload register to half the requested + // period. + // + ASSERT((ulPeriod / 2) < 65536); + HWREG(ulGen + PWM_O_X_LOAD) = ulPeriod / 2; + } + else + { + // + // In down count mode, set the reload register to the requested period + // minus one. + // + ASSERT((ulPeriod <= 65536) && (ulPeriod != 0)); + HWREG(ulGen + PWM_O_X_LOAD) = ulPeriod - 1; + } +} +#endif + +//***************************************************************************** +// +//! Gets the period of a PWM generator block. +//! +//! \param ulBase is the base address of the PWM module. +//! \param ulGen is the PWM generator to query. Must be one of +//! \b PWM_GEN_0, \b PWM_GEN_1, or \b PWM_GEN_2. +//! +//! This function gets the period of the specified PWM generator block. The +//! period of the generator block is defined as the number of \b PWM clock +//! ticks between pulses on the generator block \b zero signal. +//! +//! If the update of the counter for the specified PWM generator has yet +//! to be completed, the value returned may not be the active period. The +//! value returned is the programmed period, measured in \b PWM clock ticks. +//! +//! \return Returns the programmed period of the specified generator block +//! in \b PWM clock ticks. +// +//***************************************************************************** +#if defined(GROUP_genperiodget) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +PWMGenPeriodGet(unsigned long ulBase, unsigned long ulGen) +{ + // + // Check the arguments. + // + ASSERT(ulBase == PWM_BASE); + ASSERT((ulGen == PWM_GEN_0) || (ulGen == PWM_GEN_1) || + (ulGen == PWM_GEN_2)); + + // + // Compute the generator's base address. + // + ulGen = PWM_GEN_BADDR(ulBase, ulGen); + + // + // Figure out the counter mode. + // + if(HWREG(ulGen + PWM_O_X_CTL) & PWM_X_CTL_MODE) + { + // + // The period is twice the reload register value. + // + return(HWREG(ulGen + PWM_O_X_LOAD) * 2); + } + else + { + // + // The period is the reload register value plus one. + // + return(HWREG(ulGen + PWM_O_X_LOAD) + 1); + } +} +#endif + +//***************************************************************************** +// +//! Enables the timer/counter for a PWM generator block. +//! +//! \param ulBase is the base address of the PWM module. +//! \param ulGen is the PWM generator to be enabled. Must be one of +//! \b PWM_GEN_0, \b PWM_GEN_1, or \b PWM_GEN_2. +//! +//! This function allows the \b PWM clock to drive the timer/counter for the +//! specified generator block. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_genenable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +PWMGenEnable(unsigned long ulBase, unsigned long ulGen) +{ + // + // Check the arguments. + // + ASSERT(ulBase == PWM_BASE); + ASSERT((ulGen == PWM_GEN_0) || (ulGen == PWM_GEN_1) || + (ulGen == PWM_GEN_2)); + + // + // Enable the PWM generator. + // + HWREG(PWM_GEN_BADDR(ulBase, ulGen) + PWM_O_X_CTL) |= PWM_X_CTL_ENABLE; +} +#endif + +//***************************************************************************** +// +//! Disables the timer/counter for a PWM generator block. +//! +//! \param ulBase is the base address of the PWM module. +//! \param ulGen is the PWM generator to be disabled. Must be one of +//! \b PWM_GEN_0, \b PWM_GEN_1, or \b PWM_GEN_2. +//! +//! This function blocks the \b PWM clock from driving the timer/counter for +//! the specified generator block. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_gendisable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +PWMGenDisable(unsigned long ulBase, unsigned long ulGen) +{ + // + // Check the arguments. + // + ASSERT(ulBase == PWM_BASE); + ASSERT((ulGen == PWM_GEN_0) || (ulGen == PWM_GEN_1) || + (ulGen == PWM_GEN_2)); + + // + // Disable the PWM generator. + // + HWREG(PWM_GEN_BADDR(ulBase, + ulGen) + PWM_O_X_CTL) &= ~(PWM_X_CTL_ENABLE); +} +#endif + +//***************************************************************************** +// +//! Sets the pulse width for the specified PWM output. +//! +//! \param ulBase is the base address of the PWM module. +//! \param ulPWMOut is the PWM output to modify. Must be one of \b PWM_OUT_0, +//! \b PWM_OUT_1, \b PWM_OUT_2, \b PWM_OUT_3, \b PWM_OUT_4, or \b PWM_OUT_5. +//! \param ulWidth specifies the width of the positive portion of the pulse. +//! +//! This function sets the pulse width for the specified PWM output, where the +//! pulse width is defined as the number of \b PWM clock ticks. +//! +//! \note Any subsequent calls made to this function before an update occurs +//! will cause the previous values to be overwritten. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_pulsewidthset) || defined(BUILD_ALL) || defined(DOXYGEN) +void +PWMPulseWidthSet(unsigned long ulBase, unsigned long ulPWMOut, + unsigned long ulWidth) +{ + unsigned long ulGenBase, ulReg; + + // + // Check the arguments. + // + ASSERT(ulBase == PWM_BASE); + ASSERT((ulPWMOut == PWM_OUT_0) || (ulPWMOut == PWM_OUT_1) || + (ulPWMOut == PWM_OUT_2) || (ulPWMOut == PWM_OUT_3) || + (ulPWMOut == PWM_OUT_4) || (ulPWMOut == PWM_OUT_5)); + + // + // Compute the generator's base address. + // + ulGenBase = PWM_OUT_BADDR(ulBase, ulPWMOut); + + // + // If the counter is in up/down count mode, divide the width by two. + // + if(HWREG(ulGenBase + PWM_O_X_CTL) & PWM_X_CTL_MODE) + { + ulWidth /= 2; + } + + // + // Get the period. + // + ulReg = HWREG(ulGenBase + PWM_O_X_LOAD); + + // + // Make sure the width is not too large. + // + ASSERT(ulWidth < ulReg); + + // + // Compute the compare value. + // + ulReg = ulReg - ulWidth; + + // + // Write to the appropriate registers. + // + if(PWM_IS_OUTPUT_ODD(ulPWMOut)) + { + HWREG(ulGenBase + PWM_O_X_CMPB) = ulReg; + } + else + { + HWREG(ulGenBase + PWM_O_X_CMPA) = ulReg; + } +} +#endif + +//***************************************************************************** +// +//! Gets the pulse width of a PWM output. +//! +//! \param ulBase is the base address of the PWM module. +//! \param ulPWMOut is the PWM output to query. Must be one of \b PWM_OUT_0, +//! \b PWM_OUT_1, \b PWM_OUT_2, \b PWM_OUT_3, \b PWM_OUT_4, or \b PWM_OUT_5. +//! +//! This function gets the currently programmed pulse width for the +//! specified PWM output. If the update of the comparator for the specified +//! output has yet to be completed, the value returned may not be the active +//! pulse width. The value returned is the programmed pulse width, measured +//! in \b PWM clock ticks. +//! +//! \return Returns the width of the pulse in \b PWM clock ticks. +// +//***************************************************************************** +#if defined(GROUP_pulsewidthget) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +PWMPulseWidthGet(unsigned long ulBase, unsigned long ulPWMOut) +{ + unsigned long ulGenBase, ulReg, ulLoad; + + // + // Check the arguments. + // + ASSERT(ulBase == PWM_BASE); + ASSERT((ulPWMOut == PWM_OUT_0) || (ulPWMOut == PWM_OUT_1) || + (ulPWMOut == PWM_OUT_2) || (ulPWMOut == PWM_OUT_3) || + (ulPWMOut == PWM_OUT_4) || (ulPWMOut == PWM_OUT_5)); + + // + // Compute the generator's base address. + // + ulGenBase = PWM_OUT_BADDR(ulBase, ulPWMOut); + + // + // Then compute the pulse width. If mode is UpDown, set + // width = (load-compare)*2. Otherwise, set width = load - compare + // + ulLoad = HWREG(ulGenBase + PWM_O_X_LOAD); + if(PWM_IS_OUTPUT_ODD(ulPWMOut)) + { + ulReg = HWREG(ulGenBase + PWM_O_X_CMPB); + } + else + { + ulReg = HWREG(ulGenBase + PWM_O_X_CMPA); + } + ulReg = ulLoad - ulReg; + + // + // If in up/down count mode, double the pulse width. + // + if(HWREG(ulGenBase + PWM_O_X_CTL) & PWM_X_CTL_MODE) + { + ulReg = ulReg * 2; + } + + // + // Return the pulse width. + // + return(ulReg); +} +#endif + +//***************************************************************************** +// +//! Enables the PWM dead band output, and sets the dead band delays. +//! +//! \param ulBase is the base address of the PWM module. +//! \param ulGen is the PWM generator to modify. Must be one of +//! \b PWM_GEN_0, \b PWM_GEN_1, or \b PWM_GEN_2. +//! \param usRise specifies the width of delay from the rising edge. +//! \param usFall specifies the width of delay from the falling edge. +//! +//! This function sets the dead bands for the specified PWM generator, +//! where the dead bands are defined as the number of \b PWM clock ticks +//! from the rising or falling edge of the generator's \b OutA signal. +//! Note that this function causes the coupling of \b OutB to \b OutA. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_deadbandenable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +PWMDeadBandEnable(unsigned long ulBase, unsigned long ulGen, + unsigned short usRise, unsigned short usFall) +{ + // + // Check the arguments. + // + ASSERT(ulBase == PWM_BASE); + ASSERT((ulGen == PWM_GEN_0) || (ulGen == PWM_GEN_1) || + (ulGen == PWM_GEN_2)); + ASSERT(usRise < 4096); + ASSERT(usFall < 4096); + + // + // Compute the generator's base address. + // + ulGen = PWM_GEN_BADDR(ulBase, ulGen); + + // + // Write the dead band delay values. + // + HWREG(ulGen + PWM_O_X_DBRISE) = usRise; + HWREG(ulGen + PWM_O_X_DBFALL) = usFall; + + // + // Enable the deadband functionality. + // + HWREG(ulGen + PWM_O_X_DBCTL) |= PWM_DBCTL_ENABLE; +} +#endif + +//***************************************************************************** +// +//! Disables the PWM dead band output. +//! +//! \param ulBase is the base address of the PWM module. +//! \param ulGen is the PWM generator to modify. Must be one of +//! \b PWM_GEN_0, \b PWM_GEN_1, or \b PWM_GEN_2. +//! +//! This function disables the dead band mode for the specified PWM generator. +//! Doing so decouples the \b OutA and \b OutB signals. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_deadbanddisable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +PWMDeadBandDisable(unsigned long ulBase, unsigned long ulGen) +{ + // + // Check the arguments. + // + ASSERT(ulBase == PWM_BASE); + ASSERT((ulGen == PWM_GEN_0) || (ulGen == PWM_GEN_1) || + (ulGen == PWM_GEN_2)); + + // + // Disable the deadband functionality. + // + HWREG(PWM_GEN_BADDR(ulBase, ulGen) + PWM_O_X_DBCTL) &= ~(PWM_DBCTL_ENABLE); +} +#endif + +//***************************************************************************** +// +//! Synchronizes all pending updates. +//! +//! \param ulBase is the base address of the PWM module. +//! \param ulGenBits are the PWM generator blocks to be updated. Must be the +//! logical OR of any of \b PWM_GEN_0_BIT, \b PWM_GEN_1_BIT, or +//! \b PWM_GEN_2_BIT. +//! +//! For the selected PWM generators, this function causes all queued updates to +//! the period or pulse width to be applied the next time the corresponding +//! counter becomes zero. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_syncupdate) || defined(BUILD_ALL) || defined(DOXYGEN) +void +PWMSyncUpdate(unsigned long ulBase, unsigned long ulGenBits) +{ + // + // Check the arguments. + // + ASSERT(ulBase == PWM_BASE); + ASSERT(!(ulGenBits & ~(PWM_GEN_0_BIT | PWM_GEN_1_BIT | PWM_GEN_2_BIT))); + + // + // Update the PWM timing registers. + // + HWREG(ulBase + PWM_O_CTL) = ulGenBits; +} +#endif + +//***************************************************************************** +// +//! Synchronizes the counters in one or multiple PWM generator blocks. +//! +//! \param ulBase is the base address of the PWM module. +//! \param ulGenBits are the PWM generator blocks to be synchronized. Must be +//! the logical OR of any of \b PWM_GEN_0_BIT, \b PWM_GEN_1_BIT, or +//! \b PWM_GEN_2_BIT. +//! +//! For the selected PWM module, this function synchronizes the time base +//! of the generator blocks by causing the specified generator counters to be +//! reset to zero. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_synctimebase) || defined(BUILD_ALL) || defined(DOXYGEN) +void +PWMSyncTimeBase(unsigned long ulBase, unsigned long ulGenBits) +{ + // + // Check the arguments. + // + ASSERT(ulBase == PWM_BASE); + ASSERT(!(ulGenBits & ~(PWM_GEN_0_BIT | PWM_GEN_1_BIT | PWM_GEN_2_BIT))); + + // + // Synchronize the counters in the specified generators by writing to + // the module's synchronization register. + // + HWREG(ulBase + PWM_O_SYNC) = ulGenBits; +} +#endif + +//***************************************************************************** +// +//! Enables or disables PWM outputs. +//! +//! \param ulBase is the base address of the PWM module. +//! \param ulPWMOutBits are the PWM outputs to be modified. Must be the +//! logical OR of any of \b PWM_OUT_0_BIT, \b PWM_OUT_1_BIT, \b PWM_OUT_2_BIT, +//! \b PWM_OUT_3_BIT, \b PWM_OUT_4_BIT, or \b PWM_OUT_5_BIT. +//! \param bEnable determines if the signal is enabled or disabled. +//! +//! This function is used to enable or disable the selected PWM outputs. The +//! outputs are selected using the parameter \e ulPWMOutBits. The parameter +//! \e bEnable determines the state of the selected outputs. If \e bEnable is +//! \b true, then the selected PWM outputs are enabled, or placed in the active +//! state. If \e bEnable is \b false, then the selected outputs are disabled, +//! or placed in the inactive state. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_outputstate) || defined(BUILD_ALL) || defined(DOXYGEN) +void +PWMOutputState(unsigned long ulBase, unsigned long ulPWMOutBits, + tBoolean bEnable) +{ + // + // Check the arguments. + // + ASSERT(ulBase == PWM_BASE); + ASSERT(!(ulPWMOutBits & ~(PWM_OUT_0_BIT | PWM_OUT_1_BIT | PWM_OUT_2_BIT | + PWM_OUT_3_BIT | PWM_OUT_4_BIT | PWM_OUT_5_BIT))); + + // + // Read the module's ENABLE output control register, and set or clear + // the requested bits. + // + if(bEnable == true) + { + HWREG(ulBase + PWM_O_ENABLE) |= ulPWMOutBits; + } + else + { + HWREG(ulBase + PWM_O_ENABLE) &= ~(ulPWMOutBits); + } +} +#endif + +//***************************************************************************** +// +//! Selects the inversion mode for PWM outputs. +//! +//! \param ulBase is the base address of the PWM module. +//! \param ulPWMOutBits are the PWM outputs to be modified. Must be the +//! logical OR of any of \b PWM_OUT_0_BIT, \b PWM_OUT_1_BIT, \b PWM_OUT_2_BIT, +//! \b PWM_OUT_3_BIT, \b PWM_OUT_4_BIT, or \b PWM_OUT_5_BIT. +//! \param bInvert determines if the signal is inverted or passed through. +//! +//! This function is used to select the inversion mode for the selected PWM +//! outputs. The outputs are selected using the parameter \e ulPWMOutBits. +//! The parameter \e bInvert determines the inversion mode for the selected +//! outputs. If \e bInvert is \b true, this function will cause the specified +//! PWM output signals to be inverted, or made active low. If \e bInvert is +//! \b false, the specified output will be passed through as is, or be made +//! active high. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_outputinvert) || defined(BUILD_ALL) || defined(DOXYGEN) +void +PWMOutputInvert(unsigned long ulBase, unsigned long ulPWMOutBits, + tBoolean bInvert) +{ + // + // Check the arguments. + // + ASSERT(ulBase == PWM_BASE); + ASSERT(!(ulPWMOutBits & ~(PWM_OUT_0_BIT | PWM_OUT_1_BIT | PWM_OUT_2_BIT | + PWM_OUT_3_BIT | PWM_OUT_4_BIT | PWM_OUT_5_BIT))); + + // + // Read the module's INVERT output control register, and set or clear + // the requested bits. + // + if(bInvert == true) + { + HWREG(ulBase + PWM_O_INVERT) |= ulPWMOutBits; + } + else + { + HWREG(ulBase + PWM_O_INVERT) &= ~(ulPWMOutBits); + } +} +#endif + +//***************************************************************************** +// +//! Specifies the state of PWM outputs in response to a fault condition. +//! +//! \param ulBase is the base address of the PWM module. +//! \param ulPWMOutBits are the PWM outputs to be modified. Must be the +//! logical OR of any of \b PWM_OUT_0_BIT, \b PWM_OUT_1_BIT, \b PWM_OUT_2_BIT, +//! \b PWM_OUT_3_BIT, \b PWM_OUT_4_BIT, or \b PWM_OUT_5_BIT. +//! \param bFaultKill determines if the signal is killed or passed through +//! during an active fault condition. +//! +//! This function sets the fault handling characteristics of the selected PWM +//! outputs. The outputs are selected using the parameter \e ulPWMOutBits. +//! The parameter \e bFaultKill determines the fault handling characteristics +//! for the selected outputs. If \e bFaultKill is \b true, then the selected +//! outputs will be made inactive. If \e bFaultKill is \b false, then the +//! selected outputs are unaffected by the detected fault. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_outputfault) || defined(BUILD_ALL) || defined(DOXYGEN) +void +PWMOutputFault(unsigned long ulBase, unsigned long ulPWMOutBits, + tBoolean bFaultKill) +{ + // + // Check the arguments. + // + ASSERT(ulBase == PWM_BASE); + ASSERT(!(ulPWMOutBits & ~(PWM_OUT_0_BIT | PWM_OUT_1_BIT | PWM_OUT_2_BIT | + PWM_OUT_3_BIT | PWM_OUT_4_BIT | PWM_OUT_5_BIT))); + + // + // Read the module's FAULT output control register, and set or clear + // the requested bits. + // + if(bFaultKill == true) + { + HWREG(ulBase + PWM_O_FAULT) |= ulPWMOutBits; + } + else + { + HWREG(ulBase + PWM_O_FAULT) &= ~(ulPWMOutBits); + } +} +#endif + +//***************************************************************************** +// +//! Registers an interrupt handler for the specified PWM generator block. +//! +//! \param ulBase is the base address of the PWM module. +//! \param ulGen is the PWM generator in question. +//! \param pfnIntHandler is a pointer to the function to be called when the PWM +//! generator interrupt occurs. +//! +//! This function will ensure that the interrupt handler specified by +//! \e pfnIntHandler is called when an interrupt is detected for the specified +//! PWM generator block. This function will also enable the corresponding +//! PWM generator interrupt in the interrupt controller; individual generator +//! interrupts and interrupt sources must be enabled with PWMIntEnable() and +//! PWMGenIntTrigEnable(). +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_genintregister) || defined(BUILD_ALL) || defined(DOXYGEN) +void +PWMGenIntRegister(unsigned long ulBase, unsigned long ulGen, + void (*pfnIntHandler)(void)) +{ + unsigned long ulInt; + + // + // Check the arguments. + // + ASSERT(ulBase == PWM_BASE); + ASSERT((ulGen == PWM_GEN_0) || (ulGen == PWM_GEN_1) || + (ulGen == PWM_GEN_2)); + + // + // Get the interrupt number associated with the specified generator. + // + ulInt = INT_PWM0 + (ulGen >> 6) - 1; + + // + // Register the interrupt handler. + // + IntRegister(ulInt, pfnIntHandler); + + // + // Enable the PWMx interrupt. + // + IntEnable(ulInt); +} +#endif + +//***************************************************************************** +// +//! Removes an interrupt handler for the specified PWM generator block. +//! +//! \param ulBase is the base address of the PWM module. +//! \param ulGen is the PWM generator in question. +//! +//! This function will unregister the interrupt handler for the specified +//! PWM generator block. This function will also disable the corresponding +//! PWM generator interrupt in the interrupt controller; individual generator +//! interrupts and interrupt sources must be disabled with PWMIntDisable() and +//! PWMGenIntTrigDisable(). +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_genintunregister) || defined(BUILD_ALL) || defined(DOXYGEN) +void +PWMGenIntUnregister(unsigned long ulBase, unsigned long ulGen) +{ + unsigned long ulInt; + + // + // Check the arguments. + // + ASSERT(ulBase == PWM_BASE); + ASSERT((ulGen == PWM_GEN_0) || (ulGen == PWM_GEN_1) || + (ulGen == PWM_GEN_2)); + + // + // Get the interrupt number associated with the specified generator. + // + ulInt = INT_PWM0 + (ulGen >> 6) - 1; + + // + // Disable the PWMx interrupt. + // + IntDisable(ulInt); + + // + // Unregister the interrupt handler. + // + IntUnregister(ulInt); +} +#endif + +//***************************************************************************** +// +//! Registers an interrupt handler for a fault condition detected in a PWM +//! module. +//! +//! \param ulBase is the base address of the PWM module. +//! \param pfnIntHandler is a pointer to the function to be called when the PWM +//! fault interrupt occurs. +//! +//! This function will ensure that the interrupt handler specified by +//! \e pfnIntHandler is called when a fault interrupt is detected for the +//! selected PWM module. This function will also enable the PWM fault +//! interrupt in the NVIC; the PWM fault interrupt must also be enabled at the +//! module level using PWMIntEnable(). +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_faultintregister) || defined(BUILD_ALL) || defined(DOXYGEN) +void +PWMFaultIntRegister(unsigned long ulBase, void (*pfnIntHandler)(void)) +{ + // + // Check the arguments. + // + ASSERT(ulBase == PWM_BASE); + + // + // Register the interrupt handler, returning an error if one occurs. + // + IntRegister(INT_PWM_FAULT, pfnIntHandler); + + // + // Enable the PWM fault interrupt. + // + IntEnable(INT_PWM_FAULT); +} +#endif + +//***************************************************************************** +// +//! Removes the PWM fault condition interrupt handler. +//! +//! \param ulBase is the base address of the PWM module. +//! +//! This function will remove the interrupt handler for a PWM fault interrupt +//! from the selected PWM module. This function will also disable the PWM +//! fault interrupt in the NVIC; the PWM fault interrupt must also be disabled +//! at the module level using PWMIntDisable(). +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_faultintunregister) || defined(BUILD_ALL) || defined(DOXYGEN) +void +PWMFaultIntUnregister(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == PWM_BASE); + + // + // Disable the PWM fault interrupt. + // + IntDisable(INT_PWM_FAULT); + + // + // Unregister the interrupt handler, returning an error if one occurs. + // + IntUnregister(INT_PWM_FAULT); +} +#endif + +//***************************************************************************** +// +//! Enables interrupts and triggers for the specified PWM generator block. +//! +//! \param ulBase is the base address of the PWM module. +//! \param ulGen is the PWM generator to have interrupts and triggers enabled. +//! Must be one of \b PWM_GEN_0, \b PWM_GEN_1, or \b PWM_GEN_2. +//! \param ulIntTrig specifies the interrupts and triggers to be enabled. +//! +//! Unmasks the specified interrupt(s) and trigger(s) by setting the +//! specified bits of the interrupt/trigger enable register for the specified +//! PWM generator. The defined values for the bits are as follows: +//! +//! - PWM_INT_CNT_ZERO +//! - PWM_INT_CNT_LOAD +//! - PWM_INT_CMP_AU +//! - PWM_INT_CMP_AD +//! - PWM_INT_CMP_BU +//! - PWM_INT_CMP_BD +//! - PWM_TR_CNT_ZERO +//! - PWM_TR_CNT_LOAD +//! - PWM_TR_CMP_AU +//! - PWM_TR_CMP_AD +//! - PWM_TR_CMP_BU +//! - PWM_TR_CMP_BD +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_geninttrigenable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +PWMGenIntTrigEnable(unsigned long ulBase, unsigned long ulGen, + unsigned long ulIntTrig) +{ + // + // Check the arguments. + // + ASSERT(ulBase == PWM_BASE); + ASSERT((ulGen == PWM_GEN_0) || (ulGen == PWM_GEN_1) || + (ulGen == PWM_GEN_2)); + + // + // Enable the specified interrupts/triggers. + // + HWREG(PWM_GEN_BADDR(ulBase, ulGen) + PWM_O_X_INTEN) |= ulIntTrig; +} +#endif + +//***************************************************************************** +// +//! Disables interrupts for the specified PWM generator block. +//! +//! \param ulBase is the base address of the PWM module. +//! \param ulGen is the PWM generator to have interrupts and triggers disabled. +//! Must be one of \b PWM_GEN_0, \b PWM_GEN_1, or \b PWM_GEN_2. +//! \param ulIntTrig specifies the interrupts and triggers to be disabled. +//! +//! Masks the specified interrupt(s) and trigger(s) by clearing the +//! specified bits of the interrupt/trigger enable register for the specified +//! PWM generator. The defined values for the bits are as follows: +//! +//! - PWM_INT_CNT_ZERO +//! - PWM_INT_CNT_LOAD +//! - PWM_INT_CMP_AU +//! - PWM_INT_CMP_AD +//! - PWM_INT_CMP_BU +//! - PWM_INT_CMP_BD +//! - PWM_TR_CNT_ZERO +//! - PWM_TR_CNT_LOAD +//! - PWM_TR_CMP_AU +//! - PWM_TR_CMP_AD +//! - PWM_TR_CMP_BU +//! - PWM_TR_CMP_BD +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_geninttrigdisable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +PWMGenIntTrigDisable(unsigned long ulBase, unsigned long ulGen, + unsigned long ulIntTrig) +{ + // + // Check the arguments. + // + ASSERT(ulBase == PWM_BASE); + ASSERT((ulGen == PWM_GEN_0) || (ulGen == PWM_GEN_1) || + (ulGen == PWM_GEN_2)); + + // + // Disable the specified interrupts/triggers. + // + HWREG(PWM_GEN_BADDR(ulBase, ulGen) + PWM_O_X_INTEN) &= ~(ulIntTrig); +} +#endif + +//***************************************************************************** +// +//! Gets interrupt status for the specified PWM generator block. +//! +//! \param ulBase is the base address of the PWM module. +//! \param ulGen is the PWM generator to query. Must be one of \b PWM_GEN_0, +//! \b PWM_GEN_1, or \b PWM_GEN_2. +//! \param bMasked specifies whether masked or raw interrupt status is +//! returned. +//! +//! If \e bMasked is set as \b true, then the masked interrupt status is +//! returned; otherwise, the raw interrupt status will be returned. +//! +//! \return Returns the contents of the interrupt status register, or the +//! contents of the raw interrupt status register, for the specified +//! PWM generator. +// +//***************************************************************************** +#if defined(GROUP_genintstatus) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +PWMGenIntStatus(unsigned long ulBase, unsigned long ulGen, tBoolean bMasked) +{ + // + // Check the arguments. + // + ASSERT(ulBase == PWM_BASE); + ASSERT((ulGen == PWM_GEN_0) || (ulGen == PWM_GEN_1) || + (ulGen == PWM_GEN_2)); + + // + // Compute the generator's base address. + // + ulGen = PWM_GEN_BADDR(ulBase, ulGen); + + // + // Read and return the specified generator's raw or enabled interrupt + // status. + // + if(bMasked == true) + { + return(HWREG(ulGen + PWM_O_X_ISC)); + } + else + { + return(HWREG(ulGen + PWM_O_X_RIS)); + } +} +#endif + +//***************************************************************************** +// +//! Clears the specified interrupt(s) for the specified PWM generator block. +//! +//! \param ulBase is the base address of the PWM module. +//! \param ulGen is the PWM generator to query. Must be one of \b PWM_GEN_0, +//! \b PWM_GEN_1, or \b PWM_GEN_2. +//! \param ulInts specifies the interrupts to be cleared. +//! +//! Clears the specified interrupt(s) by writing a 1 to the specified bits +//! of the interrupt status register for the specified PWM generator. The +//! defined values for the bits are as follows: +//! +//! - PWM_INT_CNT_ZERO +//! - PWM_INT_CNT_LOAD +//! - PWM_INT_CMP_AU +//! - PWM_INT_CMP_AD +//! - PWM_INT_CMP_BU +//! - PWM_INT_CMP_BD +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_genintclear) || defined(BUILD_ALL) || defined(DOXYGEN) +void +PWMGenIntClear(unsigned long ulBase, unsigned long ulGen, unsigned long ulInts) +{ + // + // Check the arguments. + // + ASSERT(ulBase == PWM_BASE); + ASSERT((ulGen == PWM_GEN_0) || (ulGen == PWM_GEN_1) || + (ulGen == PWM_GEN_2)); + + // + // Clear the requested interrupts by writing ones to the specified bit + // of the module's interrupt enable register. + // + HWREG(PWM_GEN_BADDR(ulBase, ulGen) + PWM_O_X_ISC) = ulInts; +} +#endif + +//***************************************************************************** +// +//! Enables generator and fault interrupts for a PWM module. +//! +//! \param ulBase is the base address of the PWM module. +//! \param ulGenFault contains the interrupts to be enabled. Must be a logical +//! OR of any of \b PWM_INT_GEN_0, \b PWM_INT_GEN_1, \b PWM_INT_GEN_2, or +//! \b PWM_INT_FAULT. +//! +//! Unmasks the specified interrupt(s) by setting the specified bits of +//! the interrupt enable register for the selected PWM module. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intenable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +PWMIntEnable(unsigned long ulBase, unsigned long ulGenFault) +{ + // + // Check the arguments. + // + ASSERT(ulBase == PWM_BASE); + + // + // Read the module's interrupt enable register, and enable interrupts + // for the specified PWM generators. + // + HWREG(ulBase + PWM_O_INTEN) |= ulGenFault; +} +#endif + +//***************************************************************************** +// +//! Disables generator and fault interrupts for a PWM module. +//! +//! \param ulBase is the base address of the PWM module. +//! \param ulGenFault contains the interrupts to be disabled. Must be a +//! logical OR of any of \b PWM_INT_GEN_0, \b PWM_INT_GEN_1, \b PWM_INT_GEN_2, +//! or \b PWM_INT_FAULT. +//! +//! Masks the specified interrupt(s) by clearing the specified bits of +//! the interrupt enable register for the selected PWM module. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intdisable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +PWMIntDisable(unsigned long ulBase, unsigned long ulGenFault) +{ + // + // Check the arguments. + // + ASSERT(ulBase == PWM_BASE); + + // + // Read the module's interrupt enable register, and disable interrupts + // for the specified PWM generators. + // + HWREG(ulBase + PWM_O_INTEN) &= ~(ulGenFault); +} +#endif + +//***************************************************************************** +// +//! Clears the fault interrupt for a PWM module. +//! +//! \param ulBase is the base address of the PWM module. +//! +//! Clears the fault interrupt by writing to the appropriate bit of the +//! interrupt status register for the selected PWM module. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_faultintclear) || defined(BUILD_ALL) || defined(DOXYGEN) +void +PWMFaultIntClear(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == PWM_BASE); + + // + // Write the only writeable bit in the module's interrupt register. + // + HWREG(ulBase + PWM_O_ISC) = PWM_INT_INTFAULT; +} +#endif + +//***************************************************************************** +// +//! Gets the interrupt status for a PWM module. +//! +//! \param ulBase is the base address of the PWM module. +//! \param bMasked specifies whether masked or raw interrupt status is +//! returned. +//! +//! If \e bMasked is set as \b true, then the masked interrupt status is +//! returned; otherwise, the raw interrupt status will be returned. +//! +//! \return The current interrupt status, enumerated as a bit field of +//! \b PWM_INT_GEN_0, \b PWM_INT_GEN_1, \b PWM_INT_GEN_2, and \b PWM_INT_FAULT. +//! +//***************************************************************************** +#if defined(GROUP_intstatus) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +PWMIntStatus(unsigned long ulBase, tBoolean bMasked) +{ + // + // Check the arguments. + // + ASSERT(ulBase == PWM_BASE); + + // + // Read and return either the module's raw or enabled interrupt status. + // + if(bMasked == true) + { + return(HWREG(ulBase + PWM_O_ISC)); + } + else + { + return(HWREG(ulBase + PWM_O_RIS)); + } +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/pwm.h b/Demo/CORTEX_LM3S811_GCC/hw_include/pwm.h new file mode 100644 index 000000000..db835bacd --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/pwm.h @@ -0,0 +1,161 @@ +//***************************************************************************** +// +// pwm.h - API function protoypes for Pulse Width Modulation (PWM) ports +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +#ifndef __PWM_H__ +#define __PWM_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// The following defines are passed to PWMGenConfigure() as the ulConfig +// parameter and specify the configuration of the PWM generator. +// +//***************************************************************************** +#define PWM_GEN_MODE_DOWN 0x00000000 // Down count mode +#define PWM_GEN_MODE_UP_DOWN 0x00000002 // Up/Down count mode +#define PWM_GEN_MODE_SYNC 0x00000038 // Synchronous updates +#define PWM_GEN_MODE_NO_SYNC 0x00000000 // Immediate updates +#define PWM_GEN_MODE_DBG_RUN 0x00000004 // Continue running in debug mode +#define PWM_GEN_MODE_DBG_STOP 0x00000000 // Stop running in debug mode + +//***************************************************************************** +// +// Defines for enabling, disabling, and clearing PWM generator interrupts and +// triggers. +// +//***************************************************************************** +#define PWM_INT_CNT_ZERO 0x00000001 // Int if COUNT = 0 +#define PWM_INT_CNT_LOAD 0x00000002 // Int if COUNT = LOAD +#define PWM_INT_CNT_AU 0x00000004 // Int if COUNT = CMPA U +#define PWM_INT_CNT_AD 0x00000008 // Int if COUNT = CMPA D +#define PWM_INT_CNT_BU 0x00000010 // Int if COUNT = CMPA U +#define PWM_INT_CNT_BD 0x00000020 // Int if COUNT = CMPA D +#define PWM_TR_CNT_ZERO 0x00000100 // Trig if COUNT = 0 +#define PWM_TR_CNT_LOAD 0x00000200 // Trig if COUNT = LOAD +#define PWM_TR_CNT_AU 0x00000400 // Trig if COUNT = CMPA U +#define PWM_TR_CNT_AD 0x00000800 // Trig if COUNT = CMPA D +#define PWM_TR_CNT_BU 0x00001000 // Trig if COUNT = CMPA U +#define PWM_TR_CNT_BD 0x00002000 // Trig if COUNT = CMPA D + +//***************************************************************************** +// +// Defines for enabling, disabling, and clearing PWM interrupts. +// +//***************************************************************************** +#define PWM_INT_GEN_0 0x00000001 // Generator 0 interrupt +#define PWM_INT_GEN_1 0x00000002 // Generator 1 interrupt +#define PWM_INT_GEN_2 0x00000004 // Generator 2 interrupt +#define PWM_INT_FAULT 0x00010000 // Fault interrupt + +//***************************************************************************** +// +// Defines to identify the generators within a module. +// +//***************************************************************************** +#define PWM_GEN_0 0x00000040 // Offset address of Gen0 +#define PWM_GEN_1 0x00000080 // Offset address of Gen1 +#define PWM_GEN_2 0x000000C0 // Offset address of Gen2 + +#define PWM_GEN_0_BIT 0x00000001 // Bit-wise ID for Gen0 +#define PWM_GEN_1_BIT 0x00000002 // Bit-wise ID for Gen1 +#define PWM_GEN_2_BIT 0x00000004 // Bit-wise ID for Gen2 + +//***************************************************************************** +// +// Defines to identify the outputs within a module. +// +//***************************************************************************** +#define PWM_OUT_0 0x00000040 // Encoded offset address of PWM0 +#define PWM_OUT_1 0x00000041 // Encoded offset address of PWM1 +#define PWM_OUT_2 0x00000082 // Encoded offset address of PWM2 +#define PWM_OUT_3 0x00000083 // Encoded offset address of PWM3 +#define PWM_OUT_4 0x000000C4 // Encoded offset address of PWM4 +#define PWM_OUT_5 0x000000C5 // Encoded offset address of PWM5 + +#define PWM_OUT_0_BIT 0x00000001 // Bit-wise ID for PWM0 +#define PWM_OUT_1_BIT 0x00000002 // Bit-wise ID for PWM1 +#define PWM_OUT_2_BIT 0x00000004 // Bit-wise ID for PWM2 +#define PWM_OUT_3_BIT 0x00000008 // Bit-wise ID for PWM3 +#define PWM_OUT_4_BIT 0x00000010 // Bit-wise ID for PWM4 +#define PWM_OUT_5_BIT 0x00000020 // Bit-wise ID for PWM5 + +//***************************************************************************** +// +// API Function prototypes +// +//***************************************************************************** +extern void PWMGenConfigure(unsigned long ulBase, unsigned long ulGen, + unsigned long ulConfig); +extern void PWMGenPeriodSet(unsigned long ulBase, unsigned long ulGen, + unsigned long ulPeriod); +extern unsigned long PWMGenPeriodGet(unsigned long ulBase, + unsigned long ulGen); +extern void PWMGenEnable(unsigned long ulBase, unsigned long ulGen); +extern void PWMGenDisable(unsigned long ulBase, unsigned long ulGen); +extern void PWMPulseWidthSet(unsigned long ulBase, unsigned long ulPWMOut, + unsigned long ulWidth); +extern unsigned long PWMPulseWidthGet(unsigned long ulBase, + unsigned long ulPWMOut); +extern void PWMDeadBandEnable(unsigned long ulBase, unsigned long ulGen, + unsigned short usRise, unsigned short usFall); +extern void PWMDeadBandDisable(unsigned long ulBase, unsigned long ulGen); +extern void PWMSyncUpdate(unsigned long ulBase, unsigned long ulGenBits); +extern void PWMSyncTimeBase(unsigned long ulBase, unsigned long ulGenBits); +extern void PWMOutputState(unsigned long ulBase, unsigned long ulPWMOutBits, + tBoolean bEnable); +extern void PWMOutputInvert(unsigned long ulBase, unsigned long ulPWMOutBits, + tBoolean bInvert); +extern void PWMOutputFault(unsigned long ulBase, unsigned long ulPWMOutBits, + tBoolean bFaultKill); +extern void PWMGenIntRegister(unsigned long ulBase, unsigned long ulGen, + void (*pfnIntHandler)(void)); +extern void PWMGenIntUnregister(unsigned long ulBase, unsigned long ulGen); +extern void PWMFaultIntRegister(unsigned long ulBase, + void (*pfnIntHandler)(void)); +extern void PWMFaultIntUnregister(unsigned long ulBase); +extern void PWMGenIntTrigEnable(unsigned long ulBase, unsigned long ulGen, + unsigned long ulIntTrig); +extern void PWMGenIntTrigDisable(unsigned long ulBase, unsigned long ulGen, + unsigned long ulIntTrig); +extern unsigned long PWMGenIntStatus(unsigned long ulBase, unsigned long ulGen, + tBoolean bMasked); +extern void PWMGenIntClear(unsigned long ulBase, unsigned long ulGen, + unsigned long ulInts); +extern void PWMIntEnable(unsigned long ulBase, unsigned long ulGenFault); +extern void PWMIntDisable(unsigned long ulBase, unsigned long ulGenFault); +extern void PWMFaultIntClear(unsigned long ulBase); +extern unsigned long PWMIntStatus(unsigned long ulBase, tBoolean bMasked); + +#ifdef __cplusplus +} +#endif + +#endif // __PWM_H__ diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/qei.c b/Demo/CORTEX_LM3S811_GCC/hw_include/qei.c new file mode 100644 index 000000000..eb982de39 --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/qei.c @@ -0,0 +1,630 @@ +//***************************************************************************** +// +// qei.c - Driver for the Quadrature Encoder with Index. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +//***************************************************************************** +// +//! \addtogroup qei_api +//! @{ +// +//***************************************************************************** + +#include "../hw_ints.h" +#include "../hw_memmap.h" +#include "../hw_qei.h" +#include "../hw_types.h" +#include "debug.h" +#include "interrupt.h" +#include "qei.h" + +//***************************************************************************** +// +//! Enables the quadrature encoder. +//! +//! \param ulBase is the base address of the quadrature encoder module. +//! +//! This will enable operation of the quadrature encoder module. It must be +//! configured before it is enabled. +//! +//! \sa QEIConfigure() +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_enable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +QEIEnable(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == QEI_BASE); + + // + // Enable the QEI module. + // + HWREG(ulBase + QEI_O_CTL) |= QEI_CTL_ENABLE; +} +#endif + +//***************************************************************************** +// +//! Disables the quadrature encoder. +//! +//! \param ulBase is the base address of the quadrature encoder module. +//! +//! This will disable operation of the quadrature encoder module. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_disable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +QEIDisable(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == QEI_BASE); + + // + // Disable the QEI module. + // + HWREG(ulBase + QEI_O_CTL) &= ~(QEI_CTL_ENABLE); +} +#endif + +//***************************************************************************** +// +//! Configures the quadrature encoder. +//! +//! \param ulBase is the base address of the quadrature encoder module. +//! \param ulConfig is the configuration for the quadrature encoder. See below +//! for a description of this parameter. +//! \param ulMaxPosition specifies the maximum position value. +//! +//! This will configure the operation of the quadrature encoder. The +//! \e ulConfig parameter provides the configuration of the encoder and is the +//! logical OR of several values: +//! +//! - \b QEI_CONFIG_CAPTURE_A or \b QEI_CONFIG_CAPTURE_A_B to specify if edges +//! on channel A or on both channels A and B should be counted by the +//! position integrator and velocity accumulator. +//! - \b QEI_CONFIG_NO_RESET or \b QEI_CONFIG_RESET_IDX to specify if the +//! position integrator should be reset when the index pulse is detected. +//! - \b QEI_CONFIG_QUADRATURE or \b QEI_CONFIG_CLOCK_DIR to specify if +//! quadrature signals are being provided on ChA and ChB, or if a direction +//! signal and a clock are being provided instead. +//! - \b QEI_CONFIG_NO_SWAP or \b QEI_CONFIG_SWAP to specify if the signals +//! provided on ChA and ChB should be swapped before being processed. +//! +//! \e ulMaxPosition is the maximum value of the position integrator, and is +//! the value used to reset the position capture when in index reset mode and +//! moving in the reverse (negative) direction. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_configure) || defined(BUILD_ALL) || defined(DOXYGEN) +void +QEIConfigure(unsigned long ulBase, unsigned long ulConfig, + unsigned long ulMaxPosition) +{ + // + // Check the arguments. + // + ASSERT(ulBase == QEI_BASE); + + // + // Write the new configuration to the hardware. + // + HWREG(ulBase + QEI_O_CTL) = ((HWREG(ulBase + QEI_O_CTL) & + ~(QEI_CTL_CAPMODE | QEI_CTL_RESMODE | + QEI_CTL_SIGMODE | QEI_CTL_SWAP)) | + ulConfig); + + // + // Set the maximum position. + // + HWREG(ulBase + QEI_O_MAXPOS) = ulMaxPosition; +} +#endif + +//***************************************************************************** +// +//! Gets the current encoder position. +//! +//! \param ulBase is the base address of the quadrature encoder module. +//! +//! This returns the current position of the encoder. Depending upon the +//! configuration of the encoder, and the incident of an index pulse, this +//! value may or may not contain the expected data (i.e. if in reset on index +//! mode, if an index pulse has not been encountered, the position counter will +//! not be aligned with the index pulse yet). +//! +//! \return The current position of the encoder. +// +//***************************************************************************** +#if defined(GROUP_positionget) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +QEIPositionGet(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == QEI_BASE); + + // + // Return the current position counter. + // + return(HWREG(ulBase + QEI_O_POS)); +} +#endif + +//***************************************************************************** +// +//! Sets the current encoder position. +//! +//! \param ulBase is the base address of the quadrature encoder module. +//! \param ulPosition is the new position for the encoder. +//! +//! This sets the current position of the encoder; the encoder position will +//! then be measured relative to this value. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_positionset) || defined(BUILD_ALL) || defined(DOXYGEN) +void +QEIPositionSet(unsigned long ulBase, unsigned long ulPosition) +{ + // + // Check the arguments. + // + ASSERT(ulBase == QEI_BASE); + + // + // Set the position counter. + // + HWREG(ulBase + QEI_O_POS) = ulPosition; +} +#endif + +//***************************************************************************** +// +//! Gets the current direction of rotation. +//! +//! \param ulBase is the base address of the quadrature encoder module. +//! +//! This returns the current direction of rotation. In this case, current +//! means the most recently detected direction of the encoder; it may not be +//! presently moving but this is the direction it last moved before it stopped. +//! +//! \return 1 if moving in the forward direction or -1 if moving in the reverse +//! direction. +// +//***************************************************************************** +#if defined(GROUP_directionget) || defined(BUILD_ALL) || defined(DOXYGEN) +long +QEIDirectionGet(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == QEI_BASE); + + // + // Return the direction of rotation. + // + return((HWREG(ulBase + QEI_O_STAT) & QEI_STAT_DIRECTION) ? -1 : 1); +} +#endif + +//***************************************************************************** +// +//! Gets the encoder error indicator. +//! +//! \param ulBase is the base address of the quadrature encoder module. +//! +//! This returns the error indicator for the quadrature encoder. It is an +//! error for both of the signals of the quadrature input to change at the same +//! time. +//! +//! \return true if an error has occurred and false otherwise. +// +//***************************************************************************** +#if defined(GROUP_errorget) || defined(BUILD_ALL) || defined(DOXYGEN) +tBoolean +QEIErrorGet(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == QEI_BASE); + + // + // Return the error indicator. + // + return((HWREG(ulBase + QEI_O_STAT) & QEI_STAT_ERROR) ? true : false); +} +#endif + +//***************************************************************************** +// +//! Enables the velocity capture. +//! +//! \param ulBase is the base address of the quadrature encoder module. +//! +//! This will enable operation of the velocity capture in the quadrature +//! encoder module. It must be configured before it is enabled. Velocity +//! capture will not occur if the quadrature encoder is not enabled. +//! +//! \sa QEIVelocityConfigure() and QEIEnable() +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_velocityenable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +QEIVelocityEnable(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == QEI_BASE); + + // + // Enable the velocity capture. + // + HWREG(ulBase + QEI_O_CTL) |= QEI_CTL_VELEN; +} +#endif + +//***************************************************************************** +// +//! Disables the velocity capture. +//! +//! \param ulBase is the base address of the quadrature encoder module. +//! +//! This will disable operation of the velocity capture in the quadrature +//! encoder module. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_velocitydisable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +QEIVelocityDisable(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == QEI_BASE); + + // + // Disable the velocity capture. + // + HWREG(ulBase + QEI_O_CTL) &= ~(QEI_CTL_VELEN); +} +#endif + +//***************************************************************************** +// +//! Configures the velocity capture. +//! +//! \param ulBase is the base address of the quadrature encoder module. +//! \param ulPreDiv specifies the predivider applied to the input quadrature +//! signal before it is counted; can be one of QEI_VELDIV_1, QEI_VELDIV_2, +//! QEI_VELDIV_4, QEI_VELDIV_8, QEI_VELDIV_16, QEI_VELDIV_32, QEI_VELDIV_64, or +//! QEI_VELDIV_128. +//! \param ulPeriod specifies the number of clock ticks over which to measure +//! the velocity; must be non-zero. +//! +//! This will configure the operation of the velocity capture portion of the +//! quadrature encoder. The position increment signal is predivided as +//! specified by \e ulPreDiv before being accumulated by the velocity capture. +//! The divided signal is accumulated over \e ulPeriod system clock before +//! being saved and resetting the accumulator. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_velocityconfigure) || defined(BUILD_ALL) || defined(DOXYGEN) +void +QEIVelocityConfigure(unsigned long ulBase, unsigned long ulPreDiv, + unsigned long ulPeriod) +{ + // + // Check the arguments. + // + ASSERT(ulBase == QEI_BASE); + ASSERT(!(ulPreDiv & ~(QEI_CTL_VELDIV_M))); + ASSERT(ulPeriod != 0); + + // + // Set the velocity predivider. + // + HWREG(ulBase + QEI_O_CTL) = ((HWREG(ulBase + QEI_O_CTL) & + ~(QEI_CTL_VELDIV_M)) | ulPreDiv); + + // + // Set the timer period. + // + HWREG(ulBase + QEI_O_LOAD) = ulPeriod - 1; +} +#endif + +//***************************************************************************** +// +//! Gets the current encoder speed. +//! +//! \param ulBase is the base address of the quadrature encoder module. +//! +//! This returns the current speed of the encoder. The value returned is the +//! number of pulses detected in the specified time period; this number can be +//! multiplied by the number of time periods per second and divided by the +//! number of pulses per revolution to obtain the number of revolutions per +//! second. +//! +//! \return The number of pulses captured in the given time period. +// +//***************************************************************************** +#if defined(GROUP_velocityget) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +QEIVelocityGet(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == QEI_BASE); + + // + // Return the speed capture value. + // + return(HWREG(ulBase + QEI_O_SPEED)); +} +#endif + +//***************************************************************************** +// +//! Registers an interrupt handler for the quadrature encoder interrupt. +//! +//! \param ulBase is the base address of the quadrature encoder module. +//! \param pfnHandler is a pointer to the function to be called when the +//! quadrature encoder interrupt occurs. +//! +//! This sets the handler to be called when a quadrature encoder interrupt +//! occurs. This will enable the global interrupt in the interrupt controller; +//! specific quadrature encoder interrupts must be enabled via QEIIntEnable(). +//! It is the interrupt handler's responsibility to clear the interrupt source +//! via QEIIntClear(). +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intregister) || defined(BUILD_ALL) || defined(DOXYGEN) +void +QEIIntRegister(unsigned long ulBase, void (*pfnHandler)(void)) +{ + // + // Check the arguments. + // + ASSERT(ulBase == QEI_BASE); + + // + // Register the interrupt handler, returning an error if an error occurs. + // + IntRegister(INT_QEI, pfnHandler); + + // + // Enable the quadrature encoder interrupt. + // + IntEnable(INT_QEI); +} +#endif + +//***************************************************************************** +// +//! Unregisters an interrupt handler for the quadrature encoder interrupt. +//! +//! \param ulBase is the base address of the quadrature encoder module. +//! +//! This function will clear the handler to be called when a quadrature encoder +//! interrupt occurs. This will also mask off the interrupt in the interrupt +//! controller so that the interrupt handler no longer is called. +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intunregister) || defined(BUILD_ALL) || defined(DOXYGEN) +void +QEIIntUnregister(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == QEI_BASE); + + // + // Disable the interrupt. + // + IntDisable(INT_QEI); + + // + // Unregister the interrupt handler. + // + IntUnregister(INT_QEI); +} +#endif + +//***************************************************************************** +// +//! Enables individual quadrature encoder interrupt sources. +//! +//! \param ulBase is the base address of the quadrature encoder module. +//! \param ulIntFlags is a bit mask of the interrupt sources to be enabled. +//! Can be any of the QEI_INTERROR, QEI_INTDIR, QEI_INTTIMER, or QEI_INTINDEX +//! values. +//! +//! Enables the indicated quadrature encoder interrupt sources. Only the +//! sources that are enabled can be reflected to the processor interrupt; +//! disabled sources have no effect on the processor. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intenable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +QEIIntEnable(unsigned long ulBase, unsigned long ulIntFlags) +{ + // + // Check the arguments. + // + ASSERT(ulBase == QEI_BASE); + + // + // Enable the specified interrupts. + // + HWREG(ulBase + QEI_O_INTEN) |= ulIntFlags; +} +#endif + +//***************************************************************************** +// +//! Disables individual quadrature encoder interrupt sources. +//! +//! \param ulBase is the base address of the quadrature encoder module. +//! \param ulIntFlags is a bit mask of the interrupt sources to be disabled. +//! Can be any of the QEI_INTERROR, QEI_INTDIR, QEI_INTTIMER, or QEI_INTINDEX +//! values. +//! +//! Disables the indicated quadrature encoder interrupt sources. Only the +//! sources that are enabled can be reflected to the processor interrupt; +//! disabled sources have no effect on the processor. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intdisable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +QEIIntDisable(unsigned long ulBase, unsigned long ulIntFlags) +{ + // + // Check the arguments. + // + ASSERT(ulBase == QEI_BASE); + + // + // Disable the specified interrupts. + // + HWREG(ulBase + QEI_O_INTEN) &= ~(ulIntFlags); +} +#endif + +//***************************************************************************** +// +//! Gets the current interrupt status. +//! +//! \param ulBase is the base address of the quadrature encoder module. +//! \param bMasked is false if the raw interrupt status is required and true if +//! the masked interrupt status is required. +//! +//! This returns the interrupt status for the quadrature encoder module. +//! Either the raw interrupt status or the status of interrupts that are +//! allowed to reflect to the processor can be returned. +//! +//! \return The current interrupt status, enumerated as a bit field of +//! QEI_INTERROR, QEI_INTDIR, QEI_INTTIMER, and QEI_INTINDEX. +// +//***************************************************************************** +#if defined(GROUP_intstatus) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +QEIIntStatus(unsigned long ulBase, tBoolean bMasked) +{ + // + // Check the arguments. + // + ASSERT(ulBase == QEI_BASE); + + // + // Return either the interrupt status or the raw interrupt status as + // requested. + // + if(bMasked) + { + return(HWREG(ulBase + QEI_O_ISC)); + } + else + { + return(HWREG(ulBase + QEI_O_RIS)); + } +} +#endif + +//***************************************************************************** +// +//! Clears quadrature encoder interrupt sources. +//! +//! \param ulBase is the base address of the quadrature encoder module. +//! \param ulIntFlags is a bit mask of the interrupt sources to be cleared. +//! Can be any of the QEI_INTERROR, QEI_INTDIR, QEI_INTTIMER, or QEI_INTINDEX +//! values. +//! +//! The specified quadrature encoder interrupt sources are cleared, so that +//! they no longer assert. This must be done in the interrupt handler to keep +//! it from being called again immediately upon exit. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intclear) || defined(BUILD_ALL) || defined(DOXYGEN) +void +QEIIntClear(unsigned long ulBase, unsigned long ulIntFlags) +{ + // + // Check the arguments. + // + ASSERT(ulBase == QEI_BASE); + + // + // Clear the requested interrupt sources. + // + HWREG(ulBase + QEI_O_ISC) = ulIntFlags; +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/qei.h b/Demo/CORTEX_LM3S811_GCC/hw_include/qei.h new file mode 100644 index 000000000..3eaafaeef --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/qei.h @@ -0,0 +1,104 @@ +//***************************************************************************** +// +// qei.h - Prototypes for the Quadrature Encoder Driver. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +#ifndef __QEI_H__ +#define __QEI_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// Values that can be passed to QEIConfigure as the ulConfig paramater. +// +//***************************************************************************** +#define QEI_CONFIG_CAPTURE_A 0x00000000 // Count on ChA edges only +#define QEI_CONFIG_CAPTURE_A_B 0x00000008 // Count on ChA and ChB edges +#define QEI_CONFIG_NO_RESET 0x00000000 // Do not reset on index pulse +#define QEI_CONFIG_RESET_IDX 0x00000010 // Reset position on index pulse +#define QEI_CONFIG_QUADRATURE 0x00000000 // ChA and ChB are quadrature +#define QEI_CONFIG_CLOCK_DIR 0x00000004 // ChA and ChB are clock and dir +#define QEI_CONFIG_NO_SWAP 0x00000000 // Do not swap ChA and ChB +#define QEI_CONFIG_SWAP 0x00000002 // Swap ChA and ChB + +//***************************************************************************** +// +// Values that can be passed to QEIVelocityConfigure as the ulPreDiv parameter. +// +//***************************************************************************** +#define QEI_VELDIV_1 0x00000000 // Predivide by 1 +#define QEI_VELDIV_2 0x00000040 // Predivide by 2 +#define QEI_VELDIV_4 0x00000080 // Predivide by 4 +#define QEI_VELDIV_8 0x000000C0 // Predivide by 8 +#define QEI_VELDIV_16 0x00000100 // Predivide by 16 +#define QEI_VELDIV_32 0x00000140 // Predivide by 32 +#define QEI_VELDIV_64 0x00000180 // Predivide by 64 +#define QEI_VELDIV_128 0x000001C0 // Predivide by 128 + +//***************************************************************************** +// +// Values that can be passed to QEIEnableInts, QEIDisableInts, and QEIClearInts +// as the ulIntFlags parameter, and returned by QEIGetIntStatus. +// +//***************************************************************************** +#define QEI_INTERROR 0x00000008 // Phase error detected +#define QEI_INTDIR 0x00000004 // Direction change +#define QEI_INTTIMER 0x00000002 // Velocity timer expired +#define QEI_INTINDEX 0x00000001 // Index pulse detected + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** +extern void QEIEnable(unsigned long ulBase); +extern void QEIDisable(unsigned long ulBase); +extern void QEIConfigure(unsigned long ulBase, unsigned long ulConfig, + unsigned long ulMaxPosition); +extern unsigned long QEIPositionGet(unsigned long ulBase); +extern void QEIPositionSet(unsigned long ulBase, unsigned long ulPosition); +extern long QEIDirectionGet(unsigned long ulBase); +extern tBoolean QEIErrorGet(unsigned long ulBase); +extern void QEIVelocityEnable(unsigned long ulBase); +extern void QEIVelocityDisable(unsigned long ulBase); +extern void QEIVelocityConfigure(unsigned long ulBase, unsigned long ulPreDiv, + unsigned long ulPeriod); +extern unsigned long QEIVelocityGet(unsigned long ulBase); +extern void QEIIntRegister(unsigned long ulBase, void (*pfnHandler)(void)); +extern void QEIIntUnregister(unsigned long ulBase); +extern void QEIIntEnable(unsigned long ulBase, unsigned long ulIntFlags); +extern void QEIIntDisable(unsigned long ulBase, unsigned long ulIntFlags); +extern unsigned long QEIIntStatus(unsigned long ulBase, tBoolean bMasked); +extern void QEIIntClear(unsigned long ulBase, unsigned long ulIntFlags); + +#ifdef __cplusplus +} +#endif + +#endif // __QEI_H__ diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/ssi.c b/Demo/CORTEX_LM3S811_GCC/hw_include/ssi.c new file mode 100644 index 000000000..095aaab33 --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/ssi.c @@ -0,0 +1,609 @@ +//***************************************************************************** +// +// ssi.c - Driver for Synchronous Serial Interface. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +//***************************************************************************** +// +//! \addtogroup ssi_api +//! @{ +// +//***************************************************************************** + +#include "../hw_ints.h" +#include "../hw_memmap.h" +#include "../hw_ssi.h" +#include "../hw_types.h" +#include "debug.h" +#include "interrupt.h" +#include "ssi.h" +#include "sysctl.h" + +//***************************************************************************** +// +//! Configures the synchronous serial interface. +//! +//! \param ulBase specifies the SSI module base address. +//! \param ulProtocol specifies the data transfer protocol. +//! \param ulMode specifies the mode of operation. +//! \param ulBitRate specifies the clock rate. +//! \param ulDataWidth specifies number of bits transfered per frame. +//! +//! This function configures the synchronous serial interface. It sets +//! the SSI protocol, mode of operation, bit rate, and data width. +//! +//! The parameter \e ulProtocol defines the data frame format. The parameter +//! \e ulProtocol can be one of the following values: SSI_FRF_MOTO_MODE_0, +//! SSI_FRF_MOTO_MODE_1, SSI_FRF_MOTO_MODE_2, SSI_FRF_MOTO_MODE_3, +//! SSI_FRF_TI, or SSI_FRF_NMW. The Motorola frame formats imply the +//! following polarity and phase configurations: +//!

+//! Polarity Phase       Mode
+//!   0       0   SSI_FRF_MOTO_MODE_0
+//!   0       1   SSI_FRF_MOTO_MODE_1
+//!   1       0   SSI_FRF_MOTO_MODE_2
+//!   1       1   SSI_FRF_MOTO_MODE_3
+//! 
+//! +//! The parameter \e ulMode defines the operating mode of the SSI module. The +//! SSI module can operate as a master or slave; if a slave, the SSI can be +//! configured to disable output on its serial output line. The parameter +//! \e ulMode can be one of the following values: SSI_MODE_MASTER, +//! SSI_MODE_SLAVE, or SSI_MODE_SLAVE_OD. +//! +//! The parameter \e ulBitRate defines the bit rate for the SSI. This bit rate +//! must satisfy the following clock ratio criteria: +//! - FSSI >= 2 * bit rate (master mode) +//! - FSSI >= 12 * bit rate (slave modes) +//! +//! where FSSI is the frequency of the clock supplied to the SSI module. +//! +//! The parameter \e ulDataWidth defines the width of the data transfers. +//! The parameter \e ulDataWidth can be a value between 4 and 16, inclusive. +//! +//! The SSI clocking is dependent upon the system clock rate returned by +//! SysCtlClockGet(); if it does not return the correct system clock rate then +//! the SSI clock rate will be incorrect. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_config) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SSIConfig(unsigned long ulBase, unsigned long ulProtocol, unsigned long ulMode, + unsigned long ulBitRate, unsigned long ulDataWidth) +{ + unsigned long ulMaxBitRate; + unsigned long ulRegVal; + unsigned long ulPreDiv; + unsigned long ulSCR; + unsigned long ulSPH_SPO; + unsigned long ulClock; + + // + // Check the arguments. + // + ASSERT(ulBase == SSI_BASE); + ASSERT((ulProtocol == SSI_FRF_MOTO_MODE_0) || + (ulProtocol == SSI_FRF_MOTO_MODE_1) || + (ulProtocol == SSI_FRF_MOTO_MODE_2) || + (ulProtocol == SSI_FRF_MOTO_MODE_3) || + (ulProtocol == SSI_FRF_TI) || + (ulProtocol == SSI_FRF_NMW)); + ASSERT((ulMode == SSI_MODE_MASTER) || + (ulMode == SSI_MODE_SLAVE) || + (ulMode == SSI_MODE_SLAVE_OD)); + ASSERT((ulDataWidth >= 4) && (ulDataWidth <= 16)); + + // + // Get the processor clock rate. + // + ulClock = SysCtlClockGet(); + + // + // Validate the clock speed. + // + ASSERT(((ulMode == SSI_MODE_MASTER) && (ulBitRate <= (ulClock / 2))) || + ((ulMode != SSI_MODE_MASTER) && (ulBitRate <= (ulClock / 12)))); + ASSERT((ulClock / ulBitRate) <= (254 * 256)); + + // + // Set the mode. + // + ulRegVal = (ulMode == SSI_MODE_SLAVE_OD) ? SSI_CR1_SOD : 0; + ulRegVal |= (ulMode == SSI_MODE_MASTER) ? 0 : SSI_CR1_MS; + HWREG(ulBase + SSI_O_CR1) = ulRegVal; + + // + // Set the clock predivider. + // + ulMaxBitRate = ulClock / ulBitRate; + ulPreDiv = 0; + do + { + ulPreDiv += 2; + ulSCR = (ulMaxBitRate / ulPreDiv) - 1; + } + while(ulSCR > 255); + HWREG(ulBase + SSI_O_CPSR) = ulPreDiv; + + // + // Set protocol and clock rate. + // + ulSPH_SPO = ulProtocol << 6; + ulProtocol &= SSI_CR0_FRF_MASK; + ulRegVal = (ulSCR << 8) | ulSPH_SPO | ulProtocol | (ulDataWidth - 1); + HWREG(ulBase + SSI_O_CR0) = ulRegVal; +} +#endif + +//***************************************************************************** +// +//! Enables the synchronous serial interface. +//! +//! \param ulBase specifies the SSI module base address. +//! +//! This will enable operation of the synchronous serial interface. It must be +//! configured before it is enabled. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_enable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SSIEnable(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == SSI_BASE); + + // + // Read-modify-write the enable bit. + // + HWREG(ulBase + SSI_O_CR1) |= SSI_CR1_SSE; +} +#endif + +//***************************************************************************** +// +//! Disables the synchronous serial interface. +//! +//! \param ulBase specifies the SSI module base address. +//! +//! This will disable operation of the synchronous serial interface. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_disable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SSIDisable(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == SSI_BASE); + + // + // Read-modify-write the enable bit. + // + HWREG(ulBase + SSI_O_CR1) &= ~(SSI_CR1_SSE); +} +#endif + +//***************************************************************************** +// +//! Registers an interrupt handler for the synchronous serial interface. +//! +//! \param ulBase specifies the SSI module base address. +//! \param pfnHandler is a pointer to the function to be called when the +//! synchronous serial interface interrupt occurs. +//! +//! This sets the handler to be called when an SSI interrupt +//! occurs. This will enable the global interrupt in the interrupt controller; +//! specific SSI interrupts must be enabled via SSIIntEnable(). If necessary, +//! it is the interrupt handler's responsibility to clear the interrupt source +//! via SSIIntClear(). +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intregister) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SSIIntRegister(unsigned long ulBase, void (*pfnHandler)(void)) +{ + // + // Check the arguments. + // + ASSERT(ulBase == SSI_BASE); + + // + // Register the interrupt handler, returning an error if an error occurs. + // + IntRegister(INT_SSI, pfnHandler); + + // + // Enable the synchronous serial interface interrupt. + // + IntEnable(INT_SSI); +} +#endif + +//***************************************************************************** +// +//! Unregisters an interrupt handler for the synchronous serial interface. +//! +//! \param ulBase specifies the SSI module base address. +//! +//! This function will clear the handler to be called when a SSI +//! interrupt occurs. This will also mask off the interrupt in the interrupt +//! controller so that the interrupt handler no longer is called. +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intunregister) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SSIIntUnregister(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == SSI_BASE); + + // + // Disable the interrupt. + // + IntDisable(INT_SSI); + + // + // Unregister the interrupt handler. + // + IntUnregister(INT_SSI); +} +#endif + +//***************************************************************************** +// +//! Enables individual SSI interrupt sources. +//! +//! \param ulBase specifies the SSI module base address. +//! \param ulIntFlags is a bit mask of the interrupt sources to be enabled. +//! +//! Enables the indicated SSI interrupt sources. Only the sources that are +//! enabled can be reflected to the processor interrupt; disabled sources +//! have no effect on the processor. The parameter \e ulIntFlags Can be +//! any of the SSI_TXFF, SSI_RXFF, SSI_RXTO, or SSI_RXOR values. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intenable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SSIIntEnable(unsigned long ulBase, unsigned long ulIntFlags) +{ + // + // Check the arguments. + // + ASSERT(ulBase == SSI_BASE); + + // + // Enable the specified interrupts. + // + HWREG(ulBase + SSI_O_IM) |= ulIntFlags; +} +#endif + +//***************************************************************************** +// +//! Disables individual SSI interrupt sources. +//! +//! \param ulBase specifies the SSI module base address. +//! \param ulIntFlags is a bit mask of the interrupt sources to be disabled. +//! +//! Disables the indicated SSI interrupt sources. The parameter +//! \e ulIntFlags Can be any of the SSI_TXFF, SSI_RXFF, SSI_RXTO, +//! or SSI_RXOR values. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intdisable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SSIIntDisable(unsigned long ulBase, unsigned long ulIntFlags) +{ + // + // Check the arguments. + // + ASSERT(ulBase == SSI_BASE); + + // + // Disable the specified interrupts. + // + HWREG(ulBase + SSI_O_IM) &= ~(ulIntFlags); +} +#endif + +//***************************************************************************** +// +//! Gets the current interrupt status. +//! +//! \param ulBase specifies the SSI module base address. +//! \param bMasked is false if the raw interrupt status is required and +//! true if the masked interrupt status is required. +//! +//! This returns the interrupt status for the SSI module. +//! Either the raw interrupt status or the status of interrupts that are +//! allowed to reflect to the processor can be returned. +//! +//! \return The current interrupt status, enumerated as a bit field of +//! SSI_TXFF, SSI_RXFF, SSI_RXTO, and SSI_RXOR. +// +//***************************************************************************** +#if defined(GROUP_intstatus) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +SSIIntStatus(unsigned long ulBase, tBoolean bMasked) +{ + // + // Check the arguments. + // + ASSERT(ulBase == SSI_BASE); + + // + // Return either the interrupt status or the raw interrupt status as + // requested. + // + if(bMasked) + { + return(HWREG(ulBase + SSI_O_MIS)); + } + else + { + return(HWREG(ulBase + SSI_O_RIS)); + } +} +#endif + +//***************************************************************************** +// +//! Clears SSI interrupt sources. +//! +//! \param ulBase specifies the SSI module base address. +//! \param ulIntFlags is a bit mask of the interrupt sources to be cleared. +//! +//! The specified SSI interrupt sources are cleared, so that +//! they no longer assert. This must be done in the interrupt handler to +//! keep it from being called again immediately upon exit. +//! The parameter \e ulIntFlags can consist of either or both the SSI_RXTO +//! and SSI_RXOR values. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intclear) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SSIIntClear(unsigned long ulBase, unsigned long ulIntFlags) +{ + // + // Check the arguments. + // + ASSERT(ulBase == SSI_BASE); + + // + // Clear the requested interrupt sources. + // + HWREG(ulBase + SSI_O_ICR) = ulIntFlags; +} +#endif + +//***************************************************************************** +// +//! Puts a data element into the SSI transmit FIFO. +//! +//! \param ulBase specifies the SSI module base address. +//! \param ulData data to be transmitted over the SSI interface. +//! +//! This function will place the supplied data into the transmit FIFO of +//! the specified SSI module. +//! +//! \note The upper 32 - N bits of the \e ulData will be discarded by the +//! hardware, where N is the data width as configured by SSIConfig(). For +//! example, if the interface is configured for 8 bit data width, the upper 24 +//! bits of \e ulData will be discarded. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_dataput) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SSIDataPut(unsigned long ulBase, unsigned long ulData) +{ + // + // Check the arguments. + // + ASSERT(ulBase == SSI_BASE); + ASSERT((ulData & (0xfffffffe << (HWREG(ulBase + SSI_O_CR0) & + SSI_CR0_DSS))) == 0); + + // + // Wait until there is space. + // + while(!(HWREG(ulBase + SSI_O_SR) & SSI_SR_TNF)) + { + } + + // + // Write the data to the SSI. + // + HWREG(ulBase + SSI_O_DR) = ulData; +} +#endif + +//***************************************************************************** +// +//! Puts a data element into the SSI transmit FIFO. +//! +//! \param ulBase specifies the SSI module base address. +//! \param ulData data to be transmitted over the SSI interface. +//! +//! This function will place the supplied data into the transmit FIFO of +//! the specified SSI module. If there is no space in the FIFO, then this +//! function will return a zero. +//! +//! \note The upper 32 - N bits of the \e ulData will be discarded by the +//! hardware, where N is the data width as configured by SSIConfig(). For +//! example, if the interface is configured for 8 bit data width, the upper 24 +//! bits of \e ulData will be discarded. +//! +//! \return Returns the number of elements written to the SSI transmit FIFO. +// +//***************************************************************************** +#if defined(GROUP_datanonblockingput) || defined(BUILD_ALL) || defined(DOXYGEN) +long +SSIDataNonBlockingPut(unsigned long ulBase, unsigned long ulData) +{ + // + // Check the arguments. + // + ASSERT(ulBase == SSI_BASE); + ASSERT((ulData & (0xfffffffe << (HWREG(ulBase + SSI_O_CR0) & + SSI_CR0_DSS))) == 0); + + // + // Check for space to write. + // + if(HWREG(ulBase + SSI_O_SR) & SSI_SR_TNF) + { + HWREG(ulBase + SSI_O_DR) = ulData; + return(1); + } + else + { + return(0); + } +} +#endif + +//***************************************************************************** +// +//! Gets a data element from the SSI receive FIFO. +//! +//! \param ulBase specifies the SSI module base address. +//! \param pulData pointer to a storage location for data that was received +//! over the SSI interface. +//! +//! This function will get received data from the receive FIFO of the specified +//! SSI module, and place that data into the location specified by the +//! \e pulData parameter. +//! +//! \note Only the lower N bits of the value written to \e pulData will contain +//! valid data, where N is the data width as configured by SSIConfig(). For +//! example, if the interface is configured for 8 bit data width, only the +//! lower 8 bits of the value written to \e pulData will contain valid data. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_dataget) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SSIDataGet(unsigned long ulBase, unsigned long *pulData) +{ + // + // Check the arguments. + // + ASSERT(ulBase == SSI_BASE); + + // + // Wait until there is data to be read. + // + while(!(HWREG(ulBase + SSI_O_SR) & SSI_SR_RNE)) + { + } + + // + // Read data from SSI. + // + *pulData = HWREG(ulBase + SSI_O_DR); +} +#endif + +//***************************************************************************** +// +//! Gets a data element from the SSI receive FIFO. +//! +//! \param ulBase specifies the SSI module base address. +//! \param pulData pointer to a storage location for data that was received +//! over the SSI interface. +//! +//! This function will get received data from the receive FIFO of +//! the specified SSI module, and place that data into the location specified +//! by the \e ulData parameter. If there is no data in the FIFO, then this +//! function will return a zero. +//! +//! \note Only the lower N bits of the value written to \e pulData will contain +//! valid data, where N is the data width as configured by SSIConfig(). For +//! example, if the interface is configured for 8 bit data width, only the +//! lower 8 bits of the value written to \e pulData will contain valid data. +//! +//! \return Returns the number of elements read from the SSI receive FIFO. +// +//***************************************************************************** +#if defined(GROUP_datanonblockingget) || defined(BUILD_ALL) || defined(DOXYGEN) +long +SSIDataNonBlockingGet(unsigned long ulBase, unsigned long *pulData) +{ + // + // Check the arguments. + // + ASSERT(ulBase == SSI_BASE); + + // + // Check for data to read. + // + if(HWREG(ulBase + SSI_O_SR) & SSI_SR_RNE) + { + *pulData = HWREG(ulBase + SSI_O_DR); + return(1); + } + else + { + return(0); + } +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/ssi.h b/Demo/CORTEX_LM3S811_GCC/hw_include/ssi.h new file mode 100644 index 000000000..045d8cb02 --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/ssi.h @@ -0,0 +1,89 @@ +//***************************************************************************** +// +// ssi.h - Prototypes for the Synchronous Serial Interface Driver. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +#ifndef __SSI_H__ +#define __SSI_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// Values that can be passed to SSIIntEnable, SSIIntDisable, and SSIIntClear +// as the ulIntFlags parameter, and returned by SSIIntStatus. +// +//***************************************************************************** +#define SSI_TXFF 0x00000008 // TX FIFO half empty or less +#define SSI_RXFF 0x00000004 // RX FIFO half full or less +#define SSI_RXTO 0x00000002 // RX timeout +#define SSI_RXOR 0x00000001 // RX overrun + +//***************************************************************************** +// +// Values that can be passed to SSIConfig. +// +//***************************************************************************** +#define SSI_FRF_MOTO_MODE_0 0x00000000 // Moto fmt, polarity 0, phase 0 +#define SSI_FRF_MOTO_MODE_1 0x00000002 // Moto fmt, polarity 0, phase 1 +#define SSI_FRF_MOTO_MODE_2 0x00000001 // Moto fmt, polarity 1, phase 0 +#define SSI_FRF_MOTO_MODE_3 0x00000003 // Moto fmt, polarity 1, phase 1 +#define SSI_FRF_TI 0x00000010 // TI frame format +#define SSI_FRF_NMW 0x00000020 // National MicroWire frame format + +#define SSI_MODE_MASTER 0x00000000 // SSI master +#define SSI_MODE_SLAVE 0x00000001 // SSI slave +#define SSI_MODE_SLAVE_OD 0x00000002 // SSI slave with output disabled + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** +extern void SSIConfig(unsigned long ulBase, unsigned long ulProtocol, + unsigned long ulMode, unsigned long ulBitRate, + unsigned long ulDataWidth); +extern void SSIDataGet(unsigned long ulBase, unsigned long *pulData); +extern long SSIDataNonBlockingGet(unsigned long ulBase, + unsigned long *pulData); +extern void SSIDataPut(unsigned long ulBase, unsigned long ulData); +extern long SSIDataNonBlockingPut(unsigned long ulBase, unsigned long ulData); +extern void SSIDisable(unsigned long ulBase); +extern void SSIEnable(unsigned long ulBase); +extern void SSIIntClear(unsigned long ulBase, unsigned long ulIntFlags); +extern void SSIIntDisable(unsigned long ulBase, unsigned long ulIntFlags); +extern void SSIIntEnable(unsigned long ulBase, unsigned long ulIntFlags); +extern void SSIIntRegister(unsigned long ulBase, void(*pfnHandler)(void)); +extern unsigned long SSIIntStatus(unsigned long ulBase, tBoolean bMasked); +extern void SSIIntUnregister(unsigned long ulBase); + +#ifdef __cplusplus +} +#endif + +#endif // __SSI_H__ diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/sysctl.c b/Demo/CORTEX_LM3S811_GCC/hw_include/sysctl.c new file mode 100644 index 000000000..539d0f76d --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/sysctl.c @@ -0,0 +1,1889 @@ +//***************************************************************************** +// +// sysctl.c - Driver for the system controller. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. ALl rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +//***************************************************************************** +// +//! \addtogroup sysctl_api +//! @{ +// +//***************************************************************************** + +#include "../hw_ints.h" +#include "../hw_memmap.h" +#include "../hw_nvic.h" +#include "../hw_sysctl.h" +#include "../hw_types.h" +#include "cpu.h" +#include "debug.h" +#include "interrupt.h" +#include "sysctl.h" + +//***************************************************************************** +// +// An array that maps the "peripheral set" number (which is stored in the upper +// nibble of the SYSCTL_PERIPH_* defines) to the SYSCTL DC? register that +// contains the peripheral present bit for that peripheral. +// +//***************************************************************************** +#if defined(GROUP_puldcregs) || defined(BUILD_ALL) +const unsigned long g_pulDCRegs[] = +{ + SYSCTL_DC1, + SYSCTL_DC2, + SYSCTL_DC4, + SYSCTL_DC1 +}; +#else +extern const unsigned long g_pulDCRegs[]; +#endif + +//***************************************************************************** +// +// An array that maps the "peripheral set" number (which is stored in the upper +// nibble of the SYSCTL_PERIPH_* defines) to the SYSCTL_SRCR? register that +// controls the software reset for that peripheral. +// +//***************************************************************************** +#if defined(GROUP_pulsrcrregs) || defined(BUILD_ALL) +const unsigned long g_pulSRCRRegs[] = +{ + SYSCTL_SRCR0, + SYSCTL_SRCR1, + SYSCTL_SRCR2 +}; +#else +extern const unsigned long g_pulSRCRRegs[]; +#endif + +//***************************************************************************** +// +// An array that maps the "peripheral set" number (which is stored in the upper +// nibble of the SYSCTL_PERIPH_* defines) to the SYSCTL_RCGC? register that +// controls the run-mode enable for that peripheral. +// +//***************************************************************************** +#if defined(GROUP_pulrcgcregs) || defined(BUILD_ALL) +const unsigned long g_pulRCGCRegs[] = +{ + SYSCTL_RCGC0, + SYSCTL_RCGC1, + SYSCTL_RCGC2 +}; +#else +extern const unsigned long g_pulRCGCRegs[]; +#endif + +//***************************************************************************** +// +// An array that maps the "peripheral set" number (which is stored in the upper +// nibble of the SYSCTL_PERIPH_* defines) to the SYSCTL_SCGC? register that +// controls the sleep-mode enable for that peripheral. +// +//***************************************************************************** +#if defined(GROUP_pulscgcregs) || defined(BUILD_ALL) +const unsigned long g_pulSCGCRegs[] = +{ + SYSCTL_SCGC0, + SYSCTL_SCGC1, + SYSCTL_SCGC2 +}; +#else +extern const unsigned long g_pulSCGCRegs[]; +#endif + +//***************************************************************************** +// +// An array that maps the "peripheral set" number (which is stored in the upper +// nibble of the SYSCTL_PERIPH_* defines) to the SYSCTL_DCGC? register that +// controls the deep-sleep-mode enable for that peripheral. +// +//***************************************************************************** +#if defined(GROUP_pulDCGCregs) || defined(BUILD_ALL) +const unsigned long g_pulDCGCRegs[] = +{ + SYSCTL_DCGC0, + SYSCTL_DCGC1, + SYSCTL_DCGC2 +}; +#else +extern const unsigned long g_pulDCGCRegs[]; +#endif + +//***************************************************************************** +// +// An array that maps the crystal number in RCC to a frequency. +// +//***************************************************************************** +#if defined(GROUP_pulxtals) || defined(BUILD_ALL) +const unsigned long g_pulXtals[] = +{ + 3579545, + 3686400, + 4000000, + 4096000, + 4915200, + 5000000, + 5120000, + 6000000, + 6144000, + 7372800, + 8000000, + 8192000 +}; +#else +extern const unsigned long g_pulXtals[]; +#endif + +//***************************************************************************** +// +//! Gets the size of the SRAM. +//! +//! This function determines the size of the SRAM on the Stellaris device. +//! +//! \return The total number of bytes of SRAM. +// +//***************************************************************************** +#if defined(GROUP_sramsizeget) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +SysCtlSRAMSizeGet(void) +{ + // + // Compute the size of the SRAM. + // + return(((HWREG(SYSCTL_DC0) & SYSCTL_DC0_SRAMSZ_MASK) >> 8) + 0x100); +} +#endif + +//***************************************************************************** +// +//! Gets the size of the flash. +//! +//! This function determines the size of the flash on the Stellaris device. +//! +//! \return The total number of bytes of flash. +// +//***************************************************************************** +#if defined(GROUP_flashsizeget) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +SysCtlFlashSizeGet(void) +{ + // + // Compute the size of the flash. + // + return(((HWREG(SYSCTL_DC0) & SYSCTL_DC0_FLASHSZ_MASK) << 11) + 0x800); +} +#endif + +//***************************************************************************** +// +//! Determines if a pin is present. +//! +//! \param ulPin is the pin in question. +//! +//! Determines if a particular pin is present in the device. The PWM, analog +//! comparators, ADC, and timers have a varying number of pins across members +//! of the Stellaris family; this will determine which are present on this +//! device. +//! +//! The \b ulPin argument must be only one of the following values: +//! \b SYSCTL_PIN_PWM0, \b SYSCTL_PIN_PWM1, \b SYSCTL_PIN_PWM2, +//! \b SYSCTL_PIN_PWM3, \b SYSCTL_PIN_PWM4, \b SYSCTL_PIN_PWM5, +//! \b SYSCTL_PIN_C0MINUS, \b SYSCTL_PIN_C0PLUS, \b SYSCTL_PIN_C0O, +//! \b SYSCTL_PIN_C1MINUS, \b SYSCTL_PIN_C1PLUS, \b SYSCTL_PIN_C1O, +//! \b SYSCTL_PIN_C2MINUS, \b SYSCTL_PIN_C2PLUS, \b SYSCTL_PIN_C2O, +//! \b SYSCTL_PIN_ADC0, \b SYSCTL_PIN_ADC1, \b SYSCTL_PIN_ADC2, +//! \b SYSCTL_PIN_ADC3, \b SYSCTL_PIN_ADC4, \b SYSCTL_PIN_ADC5, +//! \b SYSCTL_PIN_ADC6, \b SYSCTL_PIN_ADC7, \b SYSCTL_PIN_CCP0, +//! \b SYSCTL_PIN_CCP1, \b SYSCTL_PIN_CCP2, \b SYSCTL_PIN_CCP3, +//! \b SYSCTL_PIN_CCP4, \b SYSCTL_PIN_CCP5, or \b SYSCTL_PIN_32KHZ. +//! +//! \return Returns \b true if the specified pin is present and \b false if it +//! is not. +// +//***************************************************************************** +#if defined(GROUP_pinpresent) || defined(BUILD_ALL) || defined(DOXYGEN) +tBoolean +SysCtlPinPresent(unsigned long ulPin) +{ + // + // Check the arguments. + // + ASSERT((ulPin == SYSCTL_PIN_PWM0) || + (ulPin == SYSCTL_PIN_PWM1) || + (ulPin == SYSCTL_PIN_PWM2) || + (ulPin == SYSCTL_PIN_PWM3) || + (ulPin == SYSCTL_PIN_PWM4) || + (ulPin == SYSCTL_PIN_PWM5) || + (ulPin == SYSCTL_PIN_C0MINUS) || + (ulPin == SYSCTL_PIN_C0PLUS) || + (ulPin == SYSCTL_PIN_C0O) || + (ulPin == SYSCTL_PIN_C1MINUS) || + (ulPin == SYSCTL_PIN_C1PLUS) || + (ulPin == SYSCTL_PIN_C1O) || + (ulPin == SYSCTL_PIN_C2MINUS) || + (ulPin == SYSCTL_PIN_C2PLUS) || + (ulPin == SYSCTL_PIN_C2O) || + (ulPin == SYSCTL_PIN_ADC0) || + (ulPin == SYSCTL_PIN_ADC1) || + (ulPin == SYSCTL_PIN_ADC2) || + (ulPin == SYSCTL_PIN_ADC3) || + (ulPin == SYSCTL_PIN_ADC4) || + (ulPin == SYSCTL_PIN_ADC5) || + (ulPin == SYSCTL_PIN_ADC6) || + (ulPin == SYSCTL_PIN_ADC7) || + (ulPin == SYSCTL_PIN_CCP0) || + (ulPin == SYSCTL_PIN_CCP1) || + (ulPin == SYSCTL_PIN_CCP2) || + (ulPin == SYSCTL_PIN_CCP3) || + (ulPin == SYSCTL_PIN_CCP4) || + (ulPin == SYSCTL_PIN_CCP5) || + (ulPin == SYSCTL_PIN_32KHZ)) + + // + // Determine if this pin is present. + // + if(HWREG(SYSCTL_DC3) & ulPin) + { + return(true); + } + else + { + return(false); + } +} +#endif + +//***************************************************************************** +// +//! Determines if a peripheral is present. +//! +//! \param ulPeripheral is the peripheral in question. +//! +//! Determines if a particular peripheral is present in the device. Each +//! member of the Stellaris family has a different peripheral set; this will +//! determine which are present on this device. +//! +//! The \b ulPeripheral argument must be only one of the following values: +//! \b SYSCTL_PERIPH_PWM, \b SYSCTL_PERIPH_ADC, \b SYSCTL_PERIPH_WDOG, +//! \b SYSCTL_PERIPH_UART0, \b SYSCTL_PERIPH_UART1, \b SYSCTL_PERIPH_SSI, +//! \b SYSCTL_PERIPH_QEI, \b SYSCTL_PERIPH_I2C, \b SYSCTL_PERIPH_TIMER0, +//! \b SYSCTL_PERIPH_TIMER1, \b SYSCTL_PERIPH_TIMER2, \b SYSCTL_PERIPH_COMP0, +//! \b SYSCTL_PERIPH_COMP1, \b SYSCTL_PERIPH_COMP2, \b SYSCTL_PERIPH_GPIOA, +//! \b SYSCTL_PERIPH_GPIOB, \b SYSCTL_PERIPH_GPIOC, \b SYSCTL_PERIPH_GPIOD, +//! \b SYSCTL_PERIPH_GPIOE, \b SYSCTL_PERIPH_MPU, \b SYSCTL_PERIPH_TEMP, or +//! \b SYSCTL_PERIPH_PLL. +//! +//! \return Returns \b true if the specified peripheral is present and \b false +//! if it is not. +// +//***************************************************************************** +#if defined(GROUP_peripheralpresent) || defined(BUILD_ALL) || defined(DOXYGEN) +tBoolean +SysCtlPeripheralPresent(unsigned long ulPeripheral) +{ + // + // Check the arguments. + // + ASSERT((ulPeripheral == SYSCTL_PERIPH_PWM) || + (ulPeripheral == SYSCTL_PERIPH_ADC) || + (ulPeripheral == SYSCTL_PERIPH_WDOG) || + (ulPeripheral == SYSCTL_PERIPH_UART0) || + (ulPeripheral == SYSCTL_PERIPH_UART1) || + (ulPeripheral == SYSCTL_PERIPH_SSI) || + (ulPeripheral == SYSCTL_PERIPH_QEI) || + (ulPeripheral == SYSCTL_PERIPH_I2C) || + (ulPeripheral == SYSCTL_PERIPH_TIMER0) || + (ulPeripheral == SYSCTL_PERIPH_TIMER1) || + (ulPeripheral == SYSCTL_PERIPH_TIMER2) || + (ulPeripheral == SYSCTL_PERIPH_COMP0) || + (ulPeripheral == SYSCTL_PERIPH_COMP1) || + (ulPeripheral == SYSCTL_PERIPH_COMP2) || + (ulPeripheral == SYSCTL_PERIPH_GPIOA) || + (ulPeripheral == SYSCTL_PERIPH_GPIOB) || + (ulPeripheral == SYSCTL_PERIPH_GPIOC) || + (ulPeripheral == SYSCTL_PERIPH_GPIOD) || + (ulPeripheral == SYSCTL_PERIPH_GPIOE) || + (ulPeripheral == SYSCTL_PERIPH_MPU) || + (ulPeripheral == SYSCTL_PERIPH_TEMP) || + (ulPeripheral == SYSCTL_PERIPH_PLL)); + + // + // Read the correct DC register and determine if this peripheral exists. + // + if(HWREG(g_pulDCRegs[ulPeripheral >> 28]) & ulPeripheral & 0x0fffffff) + { + return(true); + } + else + { + return(false); + } +} +#endif + +//***************************************************************************** +// +//! Performs a software reset of a peripheral. +//! +//! \param ulPeripheral is the peripheral to reset. +//! +//! This function performs a software reset of the specified peripheral. An +//! individual peripheral reset signal is asserted for a brief period and then +//! deasserted, leaving the peripheral in a operating state but in its reset +//! condition. +//! +//! The \b ulPeripheral argument must be only one of the following values: +//! \b SYSCTL_PERIPH_PWM, \b SYSCTL_PERIPH_ADC, \b SYSCTL_PERIPH_WDOG, +//! \b SYSCTL_PERIPH_UART0, \b SYSCTL_PERIPH_UART1, \b SYSCTL_PERIPH_SSI, +//! \b SYSCTL_PERIPH_QEI, \b SYSCTL_PERIPH_I2C, \b SYSCTL_PERIPH_TIMER0, +//! \b SYSCTL_PERIPH_TIMER1, \b SYSCTL_PERIPH_TIMER2, \b SYSCTL_PERIPH_COMP0, +//! \b SYSCTL_PERIPH_COMP1, \b SYSCTL_PERIPH_COMP2, \b SYSCTL_PERIPH_GPIOA, +//! \b SYSCTL_PERIPH_GPIOB, \b SYSCTL_PERIPH_GPIOC, \b SYSCTL_PERIPH_GPIOD, or +//! \b SYSCTL_PERIPH_GPIOE. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_peripheralreset) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SysCtlPeripheralReset(unsigned long ulPeripheral) +{ + volatile unsigned long ulDelay; + + // + // Check the arguments. + // + ASSERT((ulPeripheral == SYSCTL_PERIPH_PWM) || + (ulPeripheral == SYSCTL_PERIPH_ADC) || + (ulPeripheral == SYSCTL_PERIPH_WDOG) || + (ulPeripheral == SYSCTL_PERIPH_UART0) || + (ulPeripheral == SYSCTL_PERIPH_UART1) || + (ulPeripheral == SYSCTL_PERIPH_SSI) || + (ulPeripheral == SYSCTL_PERIPH_QEI) || + (ulPeripheral == SYSCTL_PERIPH_I2C) || + (ulPeripheral == SYSCTL_PERIPH_TIMER0) || + (ulPeripheral == SYSCTL_PERIPH_TIMER1) || + (ulPeripheral == SYSCTL_PERIPH_TIMER2) || + (ulPeripheral == SYSCTL_PERIPH_COMP0) || + (ulPeripheral == SYSCTL_PERIPH_COMP1) || + (ulPeripheral == SYSCTL_PERIPH_COMP2) || + (ulPeripheral == SYSCTL_PERIPH_GPIOA) || + (ulPeripheral == SYSCTL_PERIPH_GPIOB) || + (ulPeripheral == SYSCTL_PERIPH_GPIOC) || + (ulPeripheral == SYSCTL_PERIPH_GPIOD) || + (ulPeripheral == SYSCTL_PERIPH_GPIOE)); + + // + // Put the peripheral into the reset state. + // + HWREG(g_pulSRCRRegs[ulPeripheral >> 28]) |= ulPeripheral & 0x0fffffff; + + // + // Delay for a little bit. + // + for(ulDelay = 0; ulDelay < 16; ulDelay++) + { + } + + // + // Take the peripheral out of the reset state. + // + HWREG(g_pulSRCRRegs[ulPeripheral >> 28]) &= ~(ulPeripheral); +} +#endif + +//***************************************************************************** +// +//! Enables a peripheral. +//! +//! \param ulPeripheral is the peripheral to enable. +//! +//! Peripherals are enabled with this function. At power-up, all peripherals +//! are disabled; they must be enabled in order to operate or respond to +//! register reads/writes. +//! +//! The \b ulPeripheral argument must be only one of the following values: +//! \b SYSCTL_PERIPH_PWM, \b SYSCTL_PERIPH_ADC, \b SYSCTL_PERIPH_WDOG, +//! \b SYSCTL_PERIPH_UART0, \b SYSCTL_PERIPH_UART1, \b SYSCTL_PERIPH_SSI, +//! \b SYSCTL_PERIPH_QEI, \b SYSCTL_PERIPH_I2C, \b SYSCTL_PERIPH_TIMER0, +//! \b SYSCTL_PERIPH_TIMER1, \b SYSCTL_PERIPH_TIMER2, \b SYSCTL_PERIPH_COMP0, +//! \b SYSCTL_PERIPH_COMP1, \b SYSCTL_PERIPH_COMP2, \b SYSCTL_PERIPH_GPIOA, +//! \b SYSCTL_PERIPH_GPIOB, \b SYSCTL_PERIPH_GPIOC, \b SYSCTL_PERIPH_GPIOD, or +//! \b SYSCTL_PERIPH_GPIOE. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_peripheralenable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SysCtlPeripheralEnable(unsigned long ulPeripheral) +{ + // + // Check the arguments. + // + ASSERT((ulPeripheral == SYSCTL_PERIPH_PWM) || + (ulPeripheral == SYSCTL_PERIPH_ADC) || + (ulPeripheral == SYSCTL_PERIPH_WDOG) || + (ulPeripheral == SYSCTL_PERIPH_UART0) || + (ulPeripheral == SYSCTL_PERIPH_UART1) || + (ulPeripheral == SYSCTL_PERIPH_SSI) || + (ulPeripheral == SYSCTL_PERIPH_QEI) || + (ulPeripheral == SYSCTL_PERIPH_I2C) || + (ulPeripheral == SYSCTL_PERIPH_TIMER0) || + (ulPeripheral == SYSCTL_PERIPH_TIMER1) || + (ulPeripheral == SYSCTL_PERIPH_TIMER2) || + (ulPeripheral == SYSCTL_PERIPH_COMP0) || + (ulPeripheral == SYSCTL_PERIPH_COMP1) || + (ulPeripheral == SYSCTL_PERIPH_COMP2) || + (ulPeripheral == SYSCTL_PERIPH_GPIOA) || + (ulPeripheral == SYSCTL_PERIPH_GPIOB) || + (ulPeripheral == SYSCTL_PERIPH_GPIOC) || + (ulPeripheral == SYSCTL_PERIPH_GPIOD) || + (ulPeripheral == SYSCTL_PERIPH_GPIOE)); + + // + // Enable this peripheral. + // + HWREG(g_pulRCGCRegs[ulPeripheral >> 28]) |= ulPeripheral & 0x0fffffff; +} +#endif + +//***************************************************************************** +// +//! Disables a peripheral. +//! +//! \param ulPeripheral is the peripheral to disable. +//! +//! Peripherals are disabled with this function. Once disabled, they will not +//! operate or respond to register reads/writes. +//! +//! The \b ulPeripheral argument must be only one of the following values: +//! \b SYSCTL_PERIPH_PWM, \b SYSCTL_PERIPH_ADC, \b SYSCTL_PERIPH_WDOG, +//! \b SYSCTL_PERIPH_UART0, \b SYSCTL_PERIPH_UART1, \b SYSCTL_PERIPH_SSI, +//! \b SYSCTL_PERIPH_QEI, \b SYSCTL_PERIPH_I2C, \b SYSCTL_PERIPH_TIMER0, +//! \b SYSCTL_PERIPH_TIMER1, \b SYSCTL_PERIPH_TIMER2, \b SYSCTL_PERIPH_COMP0, +//! \b SYSCTL_PERIPH_COMP1, \b SYSCTL_PERIPH_COMP2, \b SYSCTL_PERIPH_GPIOA, +//! \b SYSCTL_PERIPH_GPIOB, \b SYSCTL_PERIPH_GPIOC, \b SYSCTL_PERIPH_GPIOD, or +//! \b SYSCTL_PERIPH_GPIOE. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_peripheraldisable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SysCtlPeripheralDisable(unsigned long ulPeripheral) +{ + // + // Check the arguments. + // + ASSERT((ulPeripheral == SYSCTL_PERIPH_PWM) || + (ulPeripheral == SYSCTL_PERIPH_ADC) || + (ulPeripheral == SYSCTL_PERIPH_WDOG) || + (ulPeripheral == SYSCTL_PERIPH_UART0) || + (ulPeripheral == SYSCTL_PERIPH_UART1) || + (ulPeripheral == SYSCTL_PERIPH_SSI) || + (ulPeripheral == SYSCTL_PERIPH_QEI) || + (ulPeripheral == SYSCTL_PERIPH_I2C) || + (ulPeripheral == SYSCTL_PERIPH_TIMER0) || + (ulPeripheral == SYSCTL_PERIPH_TIMER1) || + (ulPeripheral == SYSCTL_PERIPH_TIMER2) || + (ulPeripheral == SYSCTL_PERIPH_COMP0) || + (ulPeripheral == SYSCTL_PERIPH_COMP1) || + (ulPeripheral == SYSCTL_PERIPH_COMP2) || + (ulPeripheral == SYSCTL_PERIPH_GPIOA) || + (ulPeripheral == SYSCTL_PERIPH_GPIOB) || + (ulPeripheral == SYSCTL_PERIPH_GPIOC) || + (ulPeripheral == SYSCTL_PERIPH_GPIOD) || + (ulPeripheral == SYSCTL_PERIPH_GPIOE)); + + // + // Disable this peripheral. + // + HWREG(g_pulRCGCRegs[ulPeripheral >> 28]) &= ~(ulPeripheral & 0x0fffffff); +} +#endif + +//***************************************************************************** +// +//! Enables a peripheral in sleep mode. +//! +//! \param ulPeripheral is the peripheral to enable in sleep mode. +//! +//! This function allows a peripheral to continue operating when the processor +//! goes into sleep mode. Since the clocking configuration of the device does +//! not change, any peripheral can safely continue operating while the +//! processor is in sleep mode, and can therefore wake the processor from sleep +//! mode. +//! +//! Sleep mode clocking of peripherals must be enabled via +//! SysCtlPeripheralClockGating(); if disabled, the peripheral sleep mode +//! configuration is maintained but has no effect when sleep mode is entered. +//! +//! The \b ulPeripheral argument must be only one of the following values: +//! \b SYSCTL_PERIPH_PWM, \b SYSCTL_PERIPH_ADC, \b SYSCTL_PERIPH_WDOG, +//! \b SYSCTL_PERIPH_UART0, \b SYSCTL_PERIPH_UART1, \b SYSCTL_PERIPH_SSI, +//! \b SYSCTL_PERIPH_QEI, \b SYSCTL_PERIPH_I2C, \b SYSCTL_PERIPH_TIMER0, +//! \b SYSCTL_PERIPH_TIMER1, \b SYSCTL_PERIPH_TIMER2, \b SYSCTL_PERIPH_COMP0, +//! \b SYSCTL_PERIPH_COMP1, \b SYSCTL_PERIPH_COMP2, \b SYSCTL_PERIPH_GPIOA, +//! \b SYSCTL_PERIPH_GPIOB, \b SYSCTL_PERIPH_GPIOC, \b SYSCTL_PERIPH_GPIOD, or +//! \b SYSCTL_PERIPH_GPIOE. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_peripheralsleepenable) || defined(BUILD_ALL) || \ + defined(DOXYGEN) +void +SysCtlPeripheralSleepEnable(unsigned long ulPeripheral) +{ + // + // Check the arguments. + // + ASSERT((ulPeripheral == SYSCTL_PERIPH_PWM) || + (ulPeripheral == SYSCTL_PERIPH_ADC) || + (ulPeripheral == SYSCTL_PERIPH_WDOG) || + (ulPeripheral == SYSCTL_PERIPH_UART0) || + (ulPeripheral == SYSCTL_PERIPH_UART1) || + (ulPeripheral == SYSCTL_PERIPH_SSI) || + (ulPeripheral == SYSCTL_PERIPH_QEI) || + (ulPeripheral == SYSCTL_PERIPH_I2C) || + (ulPeripheral == SYSCTL_PERIPH_TIMER0) || + (ulPeripheral == SYSCTL_PERIPH_TIMER1) || + (ulPeripheral == SYSCTL_PERIPH_TIMER2) || + (ulPeripheral == SYSCTL_PERIPH_COMP0) || + (ulPeripheral == SYSCTL_PERIPH_COMP1) || + (ulPeripheral == SYSCTL_PERIPH_COMP2) || + (ulPeripheral == SYSCTL_PERIPH_GPIOA) || + (ulPeripheral == SYSCTL_PERIPH_GPIOB) || + (ulPeripheral == SYSCTL_PERIPH_GPIOC) || + (ulPeripheral == SYSCTL_PERIPH_GPIOD) || + (ulPeripheral == SYSCTL_PERIPH_GPIOE)); + + // + // Enable this peripheral in sleep mode. + // + HWREG(g_pulSCGCRegs[ulPeripheral >> 28]) |= ulPeripheral & 0x0fffffff; +} +#endif + +//***************************************************************************** +// +//! Disables a peripheral in sleep mode. +//! +//! \param ulPeripheral is the peripheral to disable in sleep mode. +//! +//! This function causes a peripheral to stop operating when the processor goes +//! into sleep mode. Disabling peripherals while in sleep mode helps to lower +//! the current draw of the device. If enabled (via SysCtlPeripheralEnable()), +//! the peripheral will automatically resume operation when the processor +//! leaves sleep mode, maintaining its entire state from before sleep mode was +//! entered. +//! +//! Sleep mode clocking of peripherals must be enabled via +//! SysCtlPeripheralClockGating(); if disabled, the peripheral sleep mode +//! configuration is maintained but has no effect when sleep mode is entered. +//! +//! The \b ulPeripheral argument must be only one of the following values: +//! \b SYSCTL_PERIPH_PWM, \b SYSCTL_PERIPH_ADC, \b SYSCTL_PERIPH_WDOG, +//! \b SYSCTL_PERIPH_UART0, \b SYSCTL_PERIPH_UART1, \b SYSCTL_PERIPH_SSI, +//! \b SYSCTL_PERIPH_QEI, \b SYSCTL_PERIPH_I2C, \b SYSCTL_PERIPH_TIMER0, +//! \b SYSCTL_PERIPH_TIMER1, \b SYSCTL_PERIPH_TIMER2, \b SYSCTL_PERIPH_COMP0, +//! \b SYSCTL_PERIPH_COMP1, \b SYSCTL_PERIPH_COMP2, \b SYSCTL_PERIPH_GPIOA, +//! \b SYSCTL_PERIPH_GPIOB, \b SYSCTL_PERIPH_GPIOC, \b SYSCTL_PERIPH_GPIOD, or +//! \b SYSCTL_PERIPH_GPIOE. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_peripheralsleepdisable) || defined(BUILD_ALL) || \ + defined(DOXYGEN) +void +SysCtlPeripheralSleepDisable(unsigned long ulPeripheral) +{ + // + // Check the arguments. + // + ASSERT((ulPeripheral == SYSCTL_PERIPH_PWM) || + (ulPeripheral == SYSCTL_PERIPH_ADC) || + (ulPeripheral == SYSCTL_PERIPH_WDOG) || + (ulPeripheral == SYSCTL_PERIPH_UART0) || + (ulPeripheral == SYSCTL_PERIPH_UART1) || + (ulPeripheral == SYSCTL_PERIPH_SSI) || + (ulPeripheral == SYSCTL_PERIPH_QEI) || + (ulPeripheral == SYSCTL_PERIPH_I2C) || + (ulPeripheral == SYSCTL_PERIPH_TIMER0) || + (ulPeripheral == SYSCTL_PERIPH_TIMER1) || + (ulPeripheral == SYSCTL_PERIPH_TIMER2) || + (ulPeripheral == SYSCTL_PERIPH_COMP0) || + (ulPeripheral == SYSCTL_PERIPH_COMP1) || + (ulPeripheral == SYSCTL_PERIPH_COMP2) || + (ulPeripheral == SYSCTL_PERIPH_GPIOA) || + (ulPeripheral == SYSCTL_PERIPH_GPIOB) || + (ulPeripheral == SYSCTL_PERIPH_GPIOC) || + (ulPeripheral == SYSCTL_PERIPH_GPIOD) || + (ulPeripheral == SYSCTL_PERIPH_GPIOE)); + + // + // Disable this peripheral in sleep mode. + // + HWREG(g_pulSCGCRegs[ulPeripheral >> 28]) &= ~(ulPeripheral & 0x0fffffff); +} +#endif + +//***************************************************************************** +// +//! Enables a peripheral in deep-sleep mode. +//! +//! \param ulPeripheral is the peripheral to enable in deep-sleep mode. +//! +//! This function allows a peripheral to continue operating when the processor +//! goes into deep-sleep mode. Since the clocking configuration of the device +//! may change, not all peripherals can safely continue operating while the +//! processor is in sleep mode. Those that must run at a particular frequency +//! (such as a UART) will not work as expected if the clock changes. It is the +//! responsibility of the caller to make sensible choices. +//! +//! Deep-sleep mode clocking of peripherals must be enabled via +//! SysCtlPeripheralClockGating(); if disabled, the peripheral deep-sleep mode +//! configuration is maintained but has no effect when deep-sleep mode is +//! entered. +//! +//! The \b ulPeripheral argument must be one of the following values: +//! \b SYSCTL_PERIPH_PWM, \b SYSCTL_PERIPH_ADC, \b SYSCTL_PERIPH_WDOG, +//! \b SYSCTL_PERIPH_UART0, \b SYSCTL_PERIPH_UART1, \b SYSCTL_PERIPH_SSI, +//! \b SYSCTL_PERIPH_QEI, \b SYSCTL_PERIPH_I2C, \b SYSCTL_PERIPH_TIMER0, +//! \b SYSCTL_PERIPH_TIMER1, \b SYSCTL_PERIPH_TIMER2, \b SYSCTL_PERIPH_COMP0, +//! \b SYSCTL_PERIPH_COMP1, \b SYSCTL_PERIPH_COMP2, \b SYSCTL_PERIPH_GPIOA, +//! \b SYSCTL_PERIPH_GPIOB, \b SYSCTL_PERIPH_GPIOC, \b SYSCTL_PERIPH_GPIOD, or +//! \b SYSCTL_PERIPH_GPIOE. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_peripheraldeepsleepenable) || defined(BUILD_ALL) || \ + defined(DOXYGEN) +void +SysCtlPeripheralDeepSleepEnable(unsigned long ulPeripheral) +{ + // + // Check the arguments. + // + ASSERT((ulPeripheral == SYSCTL_PERIPH_PWM) || + (ulPeripheral == SYSCTL_PERIPH_ADC) || + (ulPeripheral == SYSCTL_PERIPH_WDOG) || + (ulPeripheral == SYSCTL_PERIPH_UART0) || + (ulPeripheral == SYSCTL_PERIPH_UART1) || + (ulPeripheral == SYSCTL_PERIPH_SSI) || + (ulPeripheral == SYSCTL_PERIPH_QEI) || + (ulPeripheral == SYSCTL_PERIPH_I2C) || + (ulPeripheral == SYSCTL_PERIPH_TIMER0) || + (ulPeripheral == SYSCTL_PERIPH_TIMER1) || + (ulPeripheral == SYSCTL_PERIPH_TIMER2) || + (ulPeripheral == SYSCTL_PERIPH_COMP0) || + (ulPeripheral == SYSCTL_PERIPH_COMP1) || + (ulPeripheral == SYSCTL_PERIPH_COMP2) || + (ulPeripheral == SYSCTL_PERIPH_GPIOA) || + (ulPeripheral == SYSCTL_PERIPH_GPIOB) || + (ulPeripheral == SYSCTL_PERIPH_GPIOC) || + (ulPeripheral == SYSCTL_PERIPH_GPIOD) || + (ulPeripheral == SYSCTL_PERIPH_GPIOE)); + + // + // Enable this peripheral in deep-sleep mode. + // + HWREG(g_pulDCGCRegs[ulPeripheral >> 28]) |= ulPeripheral & 0x0fffffff; +} +#endif + +//***************************************************************************** +// +//! Disables a peripheral in deep-sleep mode. +//! +//! \param ulPeripheral is the peripheral to disable in deep-sleep mode. +//! +//! This function causes a peripheral to stop operating when the processor goes +//! into deep-sleep mode. Disabling peripherals while in deep-sleep mode helps +//! to lower the current draw of the device, and can keep peripherals that +//! require a particular clock frequency from operating when the clock changes +//! as a result of entering deep-sleep mode. If enabled (via +//! SysCtlPeripheralEnable()), the peripheral will automatically resume +//! operation when the processor leaves deep-sleep mode, maintaining its entire +//! state from before deep-sleep mode was entered. +//! +//! Deep-sleep mode clocking of peripherals must be enabled via +//! SysCtlPeripheralClockGating(); if disabled, the peripheral deep-sleep mode +//! configuration is maintained but has no effect when deep-sleep mode is +//! entered. +//! +//! The \b ulPeripheral argument must be one of the following values: +//! \b SYSCTL_PERIPH_PWM, \b SYSCTL_PERIPH_ADC, \b SYSCTL_PERIPH_WDOG, +//! \b SYSCTL_PERIPH_UART0, \b SYSCTL_PERIPH_UART1, \b SYSCTL_PERIPH_SSI, +//! \b SYSCTL_PERIPH_QEI, \b SYSCTL_PERIPH_I2C, \b SYSCTL_PERIPH_TIMER0, +//! \b SYSCTL_PERIPH_TIMER1, \b SYSCTL_PERIPH_TIMER2, \b SYSCTL_PERIPH_COMP0, +//! \b SYSCTL_PERIPH_COMP1, \b SYSCTL_PERIPH_COMP2, \b SYSCTL_PERIPH_GPIOA, +//! \b SYSCTL_PERIPH_GPIOB, \b SYSCTL_PERIPH_GPIOC, \b SYSCTL_PERIPH_GPIOD, or +//! \b SYSCTL_PERIPH_GPIOE. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_peripheraldeepsleepdisable) || defined(BUILD_ALL) || \ + defined(DOXYGEN) +void +SysCtlPeripheralDeepSleepDisable(unsigned long ulPeripheral) +{ + // + // Check the arguments. + // + ASSERT((ulPeripheral == SYSCTL_PERIPH_PWM) || + (ulPeripheral == SYSCTL_PERIPH_ADC) || + (ulPeripheral == SYSCTL_PERIPH_WDOG) || + (ulPeripheral == SYSCTL_PERIPH_UART0) || + (ulPeripheral == SYSCTL_PERIPH_UART1) || + (ulPeripheral == SYSCTL_PERIPH_SSI) || + (ulPeripheral == SYSCTL_PERIPH_QEI) || + (ulPeripheral == SYSCTL_PERIPH_I2C) || + (ulPeripheral == SYSCTL_PERIPH_TIMER0) || + (ulPeripheral == SYSCTL_PERIPH_TIMER1) || + (ulPeripheral == SYSCTL_PERIPH_TIMER2) || + (ulPeripheral == SYSCTL_PERIPH_COMP0) || + (ulPeripheral == SYSCTL_PERIPH_COMP1) || + (ulPeripheral == SYSCTL_PERIPH_COMP2) || + (ulPeripheral == SYSCTL_PERIPH_GPIOA) || + (ulPeripheral == SYSCTL_PERIPH_GPIOB) || + (ulPeripheral == SYSCTL_PERIPH_GPIOC) || + (ulPeripheral == SYSCTL_PERIPH_GPIOD) || + (ulPeripheral == SYSCTL_PERIPH_GPIOE)); + + // + // Disable this peripheral in deep-sleep mode. + // + HWREG(g_pulDCGCRegs[ulPeripheral >> 28]) &= ~(ulPeripheral & 0x0fffffff); +} +#endif + +//***************************************************************************** +// +//! Controls peripheral clock gating in sleep and deep-sleep mode. +//! +//! \param bEnable is a boolean that is \b true if the sleep and deep-sleep +//! peripheral configuration should be used and \b false if not. +//! +//! This function controls how peripherals are clocked when the processor goes +//! into sleep or deep-sleep mode. By default, the peripherals are clocked the +//! same as in run mode; if peripheral clock gating is enabled they are clocked +//! according to the configuration set by SysCtlPeripheralSleepEnable(), +//! SysCtlPeripheralSleepDisable(), SysCtlPeripheralDeepSleepEnable(), and +//! SysCtlPeripheralDeepSleepDisable(). +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_peripheralclockgating) || defined(BUILD_ALL) || \ + defined(DOXYGEN) +void +SysCtlPeripheralClockGating(tBoolean bEnable) +{ + // + // Enable peripheral clock gating as requested. + // + if(bEnable) + { + HWREG(SYSCTL_RCC) |= SYSCTL_RCC_ACG; + } + else + { + HWREG(SYSCTL_RCC) &= ~(SYSCTL_RCC_ACG); + } +} +#endif + +//***************************************************************************** +// +//! Registers an interrupt handler for the system control interrupt. +//! +//! \param pfnHandler is a pointer to the function to be called when the system +//! control interrupt occurs. +//! +//! This sets the handler to be called when a system control interrupt occurs. +//! This will enable the global interrupt in the interrupt controller; specific +//! system control interrupts must be enabled via SysCtlIntEnable(). It is the +//! interrupt handler's responsibility to clear the interrupt source via +//! SysCtlIntClear(). +//! +//! System control can generate interrupts when the PLL achieves lock, if the +//! internal LDO current limit is exceeded, if the internal oscillator fails, +//! if the main oscillator fails, if the internal LDO output voltage droops too +//! much, if the external voltage droops too much, or if the PLL fails. +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intregister) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SysCtlIntRegister(void (*pfnHandler)(void)) +{ + // + // Register the interrupt handler, returning an error if an error occurs. + // + IntRegister(INT_SYSCTL, pfnHandler); + + // + // Enable the system control interrupt. + // + IntEnable(INT_SYSCTL); +} +#endif + +//***************************************************************************** +// +//! Unregisters the interrupt handler for the system control interrupt. +//! +//! This function will clear the handler to be called when a system control +//! interrupt occurs. This will also mask off the interrupt in the interrupt +//! controller so that the interrupt handler no longer is called. +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intunregister) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SysCtlIntUnregister(void) +{ + // + // Disable the interrupt. + // + IntDisable(INT_SYSCTL); + + // + // Unregister the interrupt handler. + // + IntUnregister(INT_SYSCTL); +} +#endif + +//***************************************************************************** +// +//! Enables individual system control interrupt sources. +//! +//! \param ulInts is a bit mask of the interrupt sources to be enabled. Must +//! be a logical OR of \b SYSCTL_INT_PLL_LOCK, \b SYSCTL_INT_CUR_LIMIT, +//! \b SYSCTL_INT_IOSC_FAIL, \b SYSCTL_INT_MOSC_FAIL, \b SYSCTL_INT_POR, +//! \b SYSCTL_INT_BOR, and/or \b SYSCTL_INT_PLL_FAIL. +//! +//! Enables the indicated system control interrupt sources. Only the sources +//! that are enabled can be reflected to the processor interrupt; disabled +//! sources have no effect on the processor. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intenable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SysCtlIntEnable(unsigned long ulInts) +{ + // + // Enable the specified interrupts. + // + HWREG(SYSCTL_IMC) |= ulInts; +} +#endif + +//***************************************************************************** +// +//! Disables individual system control interrupt sources. +//! +//! \param ulInts is a bit mask of the interrupt sources to be disabled. Must +//! be a logical OR of \b SYSCTL_INT_PLL_LOCK, \b SYSCTL_INT_CUR_LIMIT, +//! \b SYSCTL_INT_IOSC_FAIL, \b SYSCTL_INT_MOSC_FAIL, \b SYSCTL_INT_POR, +//! \b SYSCTL_INT_BOR, and/or \b SYSCTL_INT_PLL_FAIL. +//! +//! Disables the indicated system control interrupt sources. Only the sources +//! that are enabled can be reflected to the processor interrupt; disabled +//! sources have no effect on the processor. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intdisable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SysCtlIntDisable(unsigned long ulInts) +{ + // + // Disable the specified interrupts. + // + HWREG(SYSCTL_IMC) &= ~(ulInts); +} +#endif + +//***************************************************************************** +// +//! Clears system control interrupt sources. +//! +//! \param ulInts is a bit mask of the interrupt sources to be cleared. Must +//! be a logical OR of \b SYSCTL_INT_PLL_LOCK, \b SYSCTL_INT_CUR_LIMIT, +//! \b SYSCTL_INT_IOSC_FAIL, \b SYSCTL_INT_MOSC_FAIL, \b SYSCTL_INT_POR, +//! \b SYSCTL_INT_BOR, and/or \b SYSCTL_INT_PLL_FAIL. +//! +//! The specified system control interrupt sources are cleared, so that they no +//! longer assert. This must be done in the interrupt handler to keep it from +//! being called again immediately upon exit. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intclear) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SysCtlIntClear(unsigned long ulInts) +{ + // + // Clear the requested interrupt sources. + // + HWREG(SYSCTL_MISC) = ulInts; +} +#endif + +//***************************************************************************** +// +//! Gets the current interrupt status. +//! +//! \param bMasked is false if the raw interrupt status is required and true if +//! the masked interrupt status is required. +//! +//! This returns the interrupt status for the system controller. Either the +//! raw interrupt status or the status of interrupts that are allowed to +//! reflect to the processor can be returned. +//! +//! \return The current interrupt status, enumerated as a bit field of +//! \b SYSCTL_INT_PLL_LOCK, \b SYSCTL_INT_CUR_LIMIT, \b SYSCTL_INT_IOSC_FAIL, +//! \b SYSCTL_INT_MOSC_FAIL, \b SYSCTL_INT_POR, \b SYSCTL_INT_BOR, and +//! \b SYSCTL_INT_PLL_FAIL. +// +//***************************************************************************** +#if defined(GROUP_intstatus) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +SysCtlIntStatus(tBoolean bMasked) +{ + // + // Return either the interrupt status or the raw interrupt status as + // requested. + // + if(bMasked) + { + return(HWREG(SYSCTL_MISC)); + } + else + { + return(HWREG(SYSCTL_RIS)); + } +} +#endif + +//***************************************************************************** +// +//! Sets the output voltage of the LDO. +//! +//! \param ulVoltage is the required output voltage from the LDO. Must be one +//! of \b SYSCTL_LDO_2_25V, \b SYSCTL_LDO_2_30V, \b SYSCTL_LDO_2_35V, +//! \b SYSCTL_LDO_2_40V, \b SYSCTL_LDO_2_45V, \b SYSCTL_LDO_2_50V, +//! \b SYSCTL_LDO_2_55V, \b SYSCTL_LDO_2_60V, \b SYSCTL_LDO_2_65V, +//! \b SYSCTL_LDO_2_70V, or \b SYSCTL_LDO_2_75V. +//! +//! This function sets the output voltage of the LDO. The default voltage is +//! 2.5 V; it can be adjusted +/- 10%. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_ldoset) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SysCtlLDOSet(unsigned long ulVoltage) +{ + // + // Check the arguments. + // + ASSERT((ulVoltage == SYSCTL_LDO_2_25V) || + (ulVoltage == SYSCTL_LDO_2_30V) || + (ulVoltage == SYSCTL_LDO_2_35V) || + (ulVoltage == SYSCTL_LDO_2_40V) || + (ulVoltage == SYSCTL_LDO_2_45V) || + (ulVoltage == SYSCTL_LDO_2_50V) || + (ulVoltage == SYSCTL_LDO_2_55V) || + (ulVoltage == SYSCTL_LDO_2_60V) || + (ulVoltage == SYSCTL_LDO_2_65V) || + (ulVoltage == SYSCTL_LDO_2_70V) || + (ulVoltage == SYSCTL_LDO_2_75V)); + + // + // Set the LDO voltage to the requested value. + // + HWREG(SYSCTL_LDOPCTL) = ulVoltage; +} +#endif + +//***************************************************************************** +// +//! Gets the output voltage of the LDO. +//! +//! This function determines the output voltage of the LDO, as specified by the +//! control register. +//! +//! \return Returns the current voltage of the LDO; will be one of +//! \b SYSCTL_LDO_2_25V, \b SYSCTL_LDO_2_30V, \b SYSCTL_LDO_2_35V, +//! \b SYSCTL_LDO_2_40V, \b SYSCTL_LDO_2_45V, \b SYSCTL_LDO_2_50V, +//! \b SYSCTL_LDO_2_55V, \b SYSCTL_LDO_2_60V, \b SYSCTL_LDO_2_65V, +//! \b SYSCTL_LDO_2_70V, or \b SYSCTL_LDO_2_75V. +// +//***************************************************************************** +#if defined(GROUP_ldoget) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +SysCtlLDOGet(void) +{ + // + // Return the LDO voltage setting. + // + return(HWREG(SYSCTL_LDOPCTL)); +} +#endif + +//***************************************************************************** +// +//! Configures the LDO failure control. +//! +//! \param ulConfig is the required LDO failure control setting; can be either +//! \b SYSCTL_LDOCFG_ARST or \b SYSCTL_LDOCFG_NORST. +//! +//! This function allows the LDO to be configured to cause a processor reset +//! when the output voltage becomes unregulated. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_ldoconfigset) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SysCtlLDOConfigSet(unsigned long ulConfig) +{ + // + // Check hte arguments. + // + ASSERT((ulConfig == SYSCTL_LDOCFG_ARST) || + (ulConfig == SYSCTL_LDOCFG_NORST)); + + // + // Set the reset control as requested. + // + HWREG(SYSCTL_LDOARST) = ulConfig; +} +#endif + +//***************************************************************************** +// +//! Resets the device. +//! +//! This function will perform a software reset of the entire device. The +//! processor and all peripherals will be reset and all device registers will +//! return to their default values (with the exception of the reset cause +//! register, which will maintain its current value but have the software reset +//! bit set as well). +//! +//! \return This function does not return. +// +//***************************************************************************** +#if defined(GROUP_reset) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SysCtlReset(void) +{ + // + // Perform a software reset request. This will cause the device to reset, + // no further code will be executed. + // + HWREG(NVIC_APINT) = NVIC_APINT_VECTKEY | NVIC_APINT_SYSRESETREQ; + + // + // The device should have reset, so this should never be reached. Just in + // case, loop forever. + // + while(1) + { + } +} +#endif + +//***************************************************************************** +// +//! Puts the processor into sleep mode. +//! +//! This function places the processor into sleep mode; it will not return +//! until the processor returns to run mode. The peripherals that are enabled +//! via SysCtlPeripheralSleepEnable() continue to operate and can wake up the +//! processor (if automatic clock gating is enabled with +//! SysCtlPeripheralClockGating(), otherwise all peripherals continue to +//! operate). +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_sleep) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SysCtlSleep(void) +{ + // + // Wait for an interrupt. + // + CPUwfi(); +} +#endif + +//***************************************************************************** +// +//! Puts the processor into deep-sleep mode. +//! +//! This function places the processor into deep-sleep mode; it will not return +//! until the processor returns to run mode. The peripherals that are enabled +//! via SysCtlPeripheralDeepSleepEnable() continue to operate and can wake up +//! the processor (if automatic clock gating is enabled with +//! SysCtlPeripheralClockGating(), otherwise all peripherals continue to +//! operate). +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_deepsleep) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SysCtlDeepSleep(void) +{ + // + // Enable deep-sleep. + // + HWREG(NVIC_SYS_CTRL) |= NVIC_SYS_CTRL_SLEEPDEEP; + + // + // Wait for an interrupt. + // + CPUwfi(); + + // + // Disable deep-sleep so that a future sleep will work correctly. + // + HWREG(NVIC_SYS_CTRL) &= ~(NVIC_SYS_CTRL_SLEEPDEEP); +} +#endif + +//***************************************************************************** +// +//! Gets the reason for a reset. +//! +//! This function will return the reason(s) for a reset. Since the reset +//! reasons are sticky until either cleared by software or an external reset, +//! multiple reset reasons may be returned if multiple resets have occurred. +//! The reset reason will be a logical OR of \b SYSCTL_CAUSE_LDO, +//! \b SYSCTL_CAUSE_SW, \b SYSCTL_CAUSE_WDOG, \b SYSCTL_CAUSE_BOR, +//! \b SYSCTL_CAUSE_POR, and/or \b SYSCTL_CAUSE_EXT. +//! +//! \return The reason(s) for a reset. +// +//***************************************************************************** +#if defined(GROUP_resetcauseget) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +SysCtlResetCauseGet(void) +{ + // + // Return the reset reasons. + // + return(HWREG(SYSCTL_RESC)); +} +#endif + +//***************************************************************************** +// +//! Clears reset reasons. +//! +//! \param ulCauses are the reset causes to be cleared; must be a logical OR of +//! \b SYSCTL_CAUSE_LDO, \b SYSCTL_CAUSE_SW, \b SYSCTL_CAUSE_WDOG, +//! \b SYSCTL_CAUSE_BOR, \b SYSCTL_CAUSE_POR, and/or \b SYSCTL_CAUSE_EXT. +//! +//! This function clears the specified sticky reset reasons. Once cleared, +//! another reset for the same reason can be detected, and a reset for a +//! different reason can be distinguished (instead of having two reset causes +//! set). If the reset reason is used by an application, all reset causes +//! should be cleared after they are retrieved with SysCtlResetCauseGet(). +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_resetcauseclear) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SysCtlResetCauseClear(unsigned long ulCauses) +{ + // + // Clear the given reset reasons. + // + HWREG(SYSCTL_RESC) &= ~(ulCauses); +} +#endif + +//***************************************************************************** +// +//! Configures the brown-out control. +//! +//! \param ulConfig is the desired configuration of the brown-out control. +//! Must be the logical OR of \b SYSCTL_BOR_RESET and/or +//! \b SYSCTL_BOR_RESAMPLE. +//! \param ulDelay is the number of internal oscillator cycles to wait before +//! resampling an asserted brown-out signal. This value only has meaning when +//! \b SYSCTL_BOR_RESAMPLE is set and must be less than 8192. +//! +//! This function configures how the brown-out control operates. It can detect +//! a brown-out by looking at only the brown-out output, or it can wait for it +//! to be active for two consecutive samples separated by a configurable time. +//! When it detects a brown-out condition, it can either reset the device or +//! generate a processor interrupt. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_brownoutconfigset) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SysCtlBrownOutConfigSet(unsigned long ulConfig, unsigned long ulDelay) +{ + // + // Check the arguments. + // + ASSERT(!(ulConfig & ~(SYSCTL_BOR_RESET | SYSCTL_BOR_RESAMPLE))); + ASSERT(ulDelay < 8192); + + // + // Configure the brown-out reset control. + // + HWREG(SYSCTL_PBORCTL) = (ulDelay << SYSCTL_PBORCTL_BOR_SH) | ulConfig; +} +#endif + +//***************************************************************************** +// +//! Sets the clocking of the device. +//! +//! \param ulConfig is the required configuration of the device clocking. +//! +//! This function configures the clocking of the device. The input crystal +//! frequency, oscillator to be used, use of the PLL, and the system clock +//! divider are all configured with this function. +//! +//! The \b ulConfig parameter is the logical OR of several different values, +//! many of which are grouped into sets where only one can be chosen. +//! +//! The system clock divider is chosen with one of the following values: +//! \b SYSCTL_SYSDIV_1, \b SYSCTL_SYSDIV_2, \b SYSCTL_SYSDIV_3, +//! \b SYSCTL_SYSDIV_4, \b SYSCTL_SYSDIV_5, \b SYSCTL_SYSDIV_6, +//! \b SYSCTL_SYSDIV_7, \b SYSCTL_SYSDIV_8, \b SYSCTL_SYSDIV_9, +//! \b SYSCTL_SYSDIV_10, \b SYSCTL_SYSDIV_11, \b SYSCTL_SYSDIV_12, +//! \b SYSCTL_SYSDIV_13, \b SYSCTL_SYSDIV_14, \b SYSCTL_SYSDIV_15, or +//! \b SYSCTL_SYSDIV_16. +//! +//! The use of the PLL is chosen with either \b SYSCTL_USE_PLL or +//! \b SYSCTL_USE_OSC. +//! +//! The external crystal frequency is chosen with one of the following values: +//! \b SYSCTL_XTAL_3_57MHZ, \b SYSCTL_XTAL_3_68MHZ, \b SYSCTL_XTAL_4MHZ, +//! \b SYSCTL_XTAL_4_09MHZ, \b SYSCTL_XTAL_4_91MHZ, \b SYSCTL_XTAL_5MHZ, +//! \b SYSCTL_XTAL_5_12MHZ, \b SYSCTL_XTAL_6MHZ, \b SYSCTL_XTAL_6_14MHZ, +//! \b SYSCTL_XTAL_7_37MHZ, \b SYSCTL_XTAL_8MHZ, or \b SYSCTL_XTAL_8_19MHZ. +//! +//! The oscillator source is chosen with one of the following values: +//! \b SYSCTL_OSC_MAIN, \b SYSCTL_OSC_INT, or \b SYSCTL_OSC_INT4. +//! +//! The internal and main oscillators are disabled with the +//! \b SYSCTL_INT_OSC_DIS and \b SYSCTL_MAIN_OSC_DIS flags, respectively. +//! The external oscillator must be enabled in order to use an external clock +//! source. Note that attempts to disable the oscillator used to clock the +//! device will be prevented by the hardware. +//! +//! To clock the system from an external source (such as an external crystal +//! oscillator), use \b SYSCTL_USE_OSC \b | \b SYSCTL_OSC_MAIN. To clock the +//! system from the main oscillator, use \b SYSCTL_USE_OSC \b | +//! \b SYSCTL_OSC_MAIN. To clock the system from the PLL, use +//! \b SYSCTL_USE_PLL \b | \b SYSCTL_OSC_MAIN, and select the appropriate +//! crystal with one of the \b SYSCTL_XTAL_xxx values. +//! +//! \note If selecting the PLL as the system clock source (i.e. via +//! \b SYSCTL_USE_PLL), this function will poll the PLL lock interrupt to +//! determine when the PLL has locked. If an interrupt handler for the +//! system control interrupt is in place, and it responds to and clears the +//! PLL lock interrupt, this function will delay until its timeout has occurred +//! instead of completing as soon as PLL lock is achieved. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_clockset) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SysCtlClockSet(unsigned long ulConfig) +{ + volatile unsigned long ulDelay; + unsigned long ulRCC; + + // + // Get the current value of the RCC register. + // + ulRCC = HWREG(SYSCTL_RCC); + + // + // Bypass the PLL and system clock dividers for now. + // + ulRCC |= SYSCTL_RCC_BYPASS; + ulRCC &= ~(SYSCTL_RCC_USE_SYSDIV); + + // + // Write the new RCC value. + // + HWREG(SYSCTL_RCC) = ulRCC; + + // + // Make sure that the PLL and system clock dividers are bypassed for now. + // + ulRCC |= SYSCTL_RCC_BYPASS; + ulRCC &= ~(SYSCTL_RCC_USE_SYSDIV); + + // + // Make sure that the required oscillators are enabled. For now, the + // previously enabled oscillators must be enabled along with the newly + // requested oscillators. + // + ulRCC &= (~(SYSCTL_RCC_IOSCDIS | SYSCTL_RCC_MOSCDIS) | + (ulConfig & (SYSCTL_RCC_IOSCDIS | SYSCTL_RCC_MOSCDIS))); + + // + // Set the new crystal value, oscillator source, and PLL configuration. + // + ulRCC &= ~(SYSCTL_RCC_XTAL_MASK | SYSCTL_RCC_OSCSRC_MASK | + SYSCTL_RCC_PWRDN | SYSCTL_RCC_OE); + ulRCC |= ulConfig & (SYSCTL_RCC_XTAL_MASK | SYSCTL_RCC_OSCSRC_MASK | + SYSCTL_RCC_PWRDN | SYSCTL_RCC_OE); + + // + // Clear the PLL lock interrupt. + // + HWREG(SYSCTL_MISC) = SYSCTL_INT_PLL_LOCK; + + // + // Write the new RCC value. + // + HWREG(SYSCTL_RCC) = ulRCC; + + // + // Wait for a bit so that new crystal value and oscillator source can take + // effect. One of the oscillators may need to be started as well. + // + for(ulDelay = 0; ulDelay < 16; ulDelay++) + { + } + + // + // Disable the appropriate oscillators. + // + ulRCC &= ~(SYSCTL_RCC_IOSCDIS | SYSCTL_RCC_MOSCDIS); + ulRCC |= ulConfig & (SYSCTL_RCC_IOSCDIS | SYSCTL_RCC_MOSCDIS); + + // + // Write the new RCC value. + // + HWREG(SYSCTL_RCC) = ulRCC; + + // + // Set the requested system divider. This will not get written + // immediately. + // + ulRCC &= ~(SYSCTL_RCC_SYSDIV_MASK | SYSCTL_RCC_USE_SYSDIV); + ulRCC |= ulConfig & (SYSCTL_RCC_SYSDIV_MASK | SYSCTL_RCC_USE_SYSDIV); + + // + // See if the PLL output is being used to clock the system. + // + if(!(ulConfig & SYSCTL_RCC_BYPASS)) + { + // + // Wait until the PLL has locked. + // + for(ulDelay = 32768; ulDelay > 0; ulDelay--) + { + if(HWREG(SYSCTL_RIS) & SYSCTL_INT_PLL_LOCK) + { + break; + } + } + + // + // Enable use of the PLL. + // + ulRCC &= ~(SYSCTL_RCC_BYPASS); + } + + // + // Write the final RCC value. + // + HWREG(SYSCTL_RCC) = ulRCC; + + // + // Delay for a little bit so that the system divider takes effect. + // + for(ulDelay = 0; ulDelay < 16; ulDelay++) + { + } +} +#endif + +//***************************************************************************** +// +//! Gets the processor clock rate. +//! +//! This function determines the clock rate of the processor clock. This is +//! also the clock rate of all the peripheral modules (with the exception of +//! PWM, which has its own clock divider). +//! +//! \note This will not return accurate results if SysCtlClockSet() has not +//! been called to configure the clocking of the device, or if the device is +//! directly clocked from a crystal (or a clock source) that is not one of the +//! supported crystal frequencies. In the later case, this function should be +//! modified to directly return the correct system clock rate. +//! +//! \return The processor clock rate. +// +//***************************************************************************** +#if defined(GROUP_clockget) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +SysCtlClockGet(void) +{ + unsigned long ulRCC, ulPLL, ulClk; + + // + // Read RCC. + // + ulRCC = HWREG(SYSCTL_RCC); + + // + // Get the base clock rate. + // + switch(ulRCC & SYSCTL_RCC_OSCSRC_MASK) + { + // + // The main oscillator is the clock source. Determine its rate from + // the crystal setting field. + // + case SYSCTL_RCC_OSCSRC_MAIN: + { + ulClk = g_pulXtals[((ulRCC & SYSCTL_RCC_XTAL_MASK) >> + SYSCTL_RCC_XTAL_SHIFT) - + (SYSCTL_RCC_XTAL_3_57MHZ >> + SYSCTL_RCC_XTAL_SHIFT)]; + break; + } + + // + // The internal oscillator is the source clock. This is not an + // accurate clock (it is +/- 50%); what is used is the nominal. + // + case SYSCTL_RCC_OSCSRC_INT: + { + ulClk = 15000000; + break; + } + + // + // The internal oscillator divided by four is the source clock. This + // is not an accurate clock (it is +/- 50%); what is used is the + // nominal. + // + case SYSCTL_RCC_OSCSRC_INT4: + { + ulClk = 15000000 / 4; + break; + } + + // + // An unknown setting, so return a zero clock (i.e. an unknown clock + // rate). + // + default: + { + return(0); + } + } + + // + // See if the PLL is being used. + // + if(!(ulRCC & SYSCTL_RCC_BYPASS)) + { + // + // Get the PLL configuration. + // + ulPLL = HWREG(SYSCTL_PLLCFG); + + // + // Compute the PLL output frequency based on its input frequency. + // + ulClk = ((ulClk * (((ulPLL & SYSCTL_PLLCFG_F_MASK) >> + SYSCTL_PLLCFG_F_SHIFT) + 2)) / + (((ulPLL & SYSCTL_PLLCFG_R_MASK) >> + SYSCTL_PLLCFG_R_SHIFT) + 2)); + + // + // See if the optional output divide by 2 is being used. + // + if(ulPLL & SYSCTL_PLLCFG_OD_2) + { + ulClk /= 2; + } + + // + // See if the optional output divide by 4 is being used. + // + if(ulPLL & SYSCTL_PLLCFG_OD_4) + { + ulClk /= 4; + } + } + + // + // See if the system divider is being used. + // + if(ulRCC & SYSCTL_RCC_USE_SYSDIV) + { + // + // Adjust the clock rate by the system clock divider. + // + ulClk /= ((ulRCC & SYSCTL_RCC_SYSDIV_MASK) >> + SYSCTL_RCC_SYSDIV_SHIFT) + 1; + } + + // + // Return the computed clock rate. + // + return(ulClk); +} +#endif + +//***************************************************************************** +// +//! Sets the PWM clock configuration. +//! +//! \param ulConfig is the configuration for the PWM clock; it must be one of +//! \b SYSCTL_PWMDIV_1, \b SYSCTL_PWMDIV_2, \b SYSCTL_PWMDIV_4, +//! \b SYSCTL_PWMDIV_8, \b SYSCTL_PWMDIV_16, \b SYSCTL_PWMDIV_32, or +//! \b SYSCTL_PWMDIV_64. +//! +//! This function sets the rate of the clock provided to the PWM module as a +//! ratio of the processor clock. This clock is used by the PWM module to +//! generate PWM signals; its rate forms the basis for all PWM signals. +//! +//! \note The clocking of the PWM is dependent upon the system clock rate as +//! configured by SysCtlClockSet(). +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_pwmclockset) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SysCtlPWMClockSet(unsigned long ulConfig) +{ + // + // Check the arguments. + // + ASSERT((ulConfig == SYSCTL_PWMDIV_1) || + (ulConfig == SYSCTL_PWMDIV_2) || + (ulConfig == SYSCTL_PWMDIV_4) || + (ulConfig == SYSCTL_PWMDIV_8) || + (ulConfig == SYSCTL_PWMDIV_16) || + (ulConfig == SYSCTL_PWMDIV_32) || + (ulConfig == SYSCTL_PWMDIV_64)); + + // + // Check that there is a PWM block on this part. + // + ASSERT(HWREG(SYSCTL_DC1) & SYSCTL_DC1_PWM); + + // + // Set the PWM clock configuration into the run-mode clock configuration + // register. + // + HWREG(SYSCTL_RCC) = ((HWREG(SYSCTL_RCC) & + ~(SYSCTL_RCC_USE_PWMDIV | SYSCTL_RCC_PWMDIV_MASK)) | + ulConfig); +} +#endif + +//***************************************************************************** +// +//! Gets the current PWM clock configuration. +//! +//! This function returns the current PWM clock configuration. +//! +//! \return The current PWM clock configuration; will be one of +//! \b SYSCTL_PWMDIV_1, \b SYSCTL_PWMDIV_2, \b SYSCTL_PWMDIV_4, +//! \b SYSCTL_PWMDIV_8, \b SYSCTL_PWMDIV_16, \b SYSCTL_PWMDIV_32, or +//! \b SYSCTL_PWMDIV_64. +// +//***************************************************************************** +#if defined(GROUP_pwmclockget) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +SysCtlPWMClockGet(void) +{ + // + // Check that there is a PWM block on this part. + // + ASSERT(HWREG(SYSCTL_DC1) & SYSCTL_DC1_PWM); + + // + // Return the current PWM clock configuration. + // + return(HWREG(SYSCTL_RCC) & + (SYSCTL_RCC_USE_PWMDIV | SYSCTL_RCC_PWMDIV_MASK)); +} +#endif + +//***************************************************************************** +// +//! Sets the sample rate of the ADC. +//! +//! \param ulSpeed is the desired sample rate of the ADC; must be one of +//! \b SYSCTL_ADCSPEED_1MSPS, \b SYSCTL_ADCSPEED_500KSPS, +//! \b SYSCTL_ADCSPEED_250KSPS, or \b SYSCTL_ADCSPEED_125KSPS. +//! +//! This function sets the rate at which the ADC samples are captured by the +//! ADC block. The sampling speed may be limited by the hardware, so the +//! sample rate may end up being slower than requested. SysCtlADCSpeedGet() +//! will return the actual speed in use. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_adcspeedset) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SysCtlADCSpeedSet(unsigned long ulSpeed) +{ + // + // Check the arguments. + // + ASSERT((ulSpeed == SYSCTL_ADCSPEED_1MSPS) || + (ulSpeed == SYSCTL_ADCSPEED_500KSPS) || + (ulSpeed == SYSCTL_ADCSPEED_250KSPS) || + (ulSpeed == SYSCTL_ADCSPEED_125KSPS)); + + // + // Check that there is an ADC block on this part. + // + ASSERT(HWREG(SYSCTL_DC1) & SYSCTL_DC1_ADC); + + // + // Set the ADC speed in run, sleep, and deep-sleep mode. + // + HWREG(SYSCTL_RCGC0) = ((HWREG(SYSCTL_RCGC0) & ~(SYSCTL_SET0_ADCSPD_MASK)) | + ulSpeed); + HWREG(SYSCTL_SCGC0) = ((HWREG(SYSCTL_SCGC0) & ~(SYSCTL_SET0_ADCSPD_MASK)) | + ulSpeed); + HWREG(SYSCTL_DCGC0) = ((HWREG(SYSCTL_DCGC0) & ~(SYSCTL_SET0_ADCSPD_MASK)) | + ulSpeed); +} +#endif + +//***************************************************************************** +// +//! Gets the sample rate of the ADC. +//! +//! This function gets the current sample rate of the ADC. +//! +//! \return Returns the current ADC sample rate; will be one of +//! \b SYSCTL_ADCSPEED_1MSPS, \b SYSCTL_ADCSPEED_500KSPS, +//! \b SYSCTL_ADCSPEED_250KSPS, or \b SYSCTL_ADCSPEED_125KSPS. +// +//***************************************************************************** +#if defined(GROUP_adcspeedget) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +SysCtlADCSpeedGet(void) +{ + // + // Check that there is an ADC block on this part. + // + ASSERT(HWREG(SYSCTL_DC1) & SYSCTL_DC1_ADC); + + // + // Return the current ADC speed. + // + return(HWREG(SYSCTL_RCGC0) & SYSCTL_SET0_ADCSPD_MASK); +} +#endif + +//***************************************************************************** +// +//! Configures the internal oscillator verification timer. +//! +//! \param bEnable is a boolean that is \b true if the internal oscillator +//! verification timer should be enabled. +//! +//! This function allows the internal oscillator verification timer to be +//! enabled or disabled. When enabled, an interrupt will be generated if the +//! internal oscillator ceases to operate. +//! +//! \note Both oscillators (main and internal) must be enabled for this +//! verification timer to operate as the main oscillator will verify the +//! internal oscillator. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_boscverificationset) || defined(BUILD_ALL) || \ + defined(DOXYGEN) +void +SysCtlIOSCVerificationSet(tBoolean bEnable) +{ + // + // Enable or disable the internal oscillator verification timer as + // requested. + // + if(bEnable) + { + HWREG(SYSCTL_RCC) |= SYSCTL_RCC_IOSCVER; + } + else + { + HWREG(SYSCTL_RCC) &= ~(SYSCTL_RCC_IOSCVER); + } +} +#endif + +//***************************************************************************** +// +//! Configures the main oscillator verification timer. +//! +//! \param bEnable is a boolean that is \b true if the main oscillator +//! verification timer should be enabled. +//! +//! This function allows the main oscillator verification timer to be enabled +//! or disabled. When enabled, an interrupt will be generated if the main +//! oscillator ceases to operate. +//! +//! \note Both oscillators (main and internal) must be enabled for this +//! verification timer to operate as the internal oscillator will verify the +//! main oscillator. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_moscverificationset) || defined(BUILD_ALL) || \ + defined(DOXYGEN) +void +SysCtlMOSCVerificationSet(tBoolean bEnable) +{ + // + // Enable or disable the main oscillator verification timer as requested. + // + if(bEnable) + { + HWREG(SYSCTL_RCC) |= SYSCTL_RCC_MOSCVER; + } + else + { + HWREG(SYSCTL_RCC) &= ~(SYSCTL_RCC_MOSCVER); + } +} +#endif + +//***************************************************************************** +// +//! Configures the PLL verification timer. +//! +//! \param bEnable is a boolean that is \b true if the PLL verification timer +//! should be enabled. +//! +//! This function allows the PLL verification timer to be enabled or disabled. +//! When enabled, an interrupt will be generated if the PLL ceases to operate. +//! +//! \note The main oscillator must be enabled for this verification timer to +//! operate as it is used to check the PLL. Also, the verification timer +//! should be disabled while the PLL is being reconfigured via +//! SysCtlClockSet(). +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_pllverificationset) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SysCtlPLLVerificationSet(tBoolean bEnable) +{ + // + // Enable or disable the PLL verification timer as requested. + // + if(bEnable) + { + HWREG(SYSCTL_RCC) |= SYSCTL_RCC_PLLVER; + } + else + { + HWREG(SYSCTL_RCC) &= ~(SYSCTL_RCC_PLLVER); + } +} +#endif + +//***************************************************************************** +// +//! Clears the clock verification status. +//! +//! This function clears the status of the clock verification timers, allowing +//! them to assert another failure if detected. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_clkverificationclear) || defined(BUILD_ALL) || \ + defined(DOXYGEN) +void +SysCtlClkVerificationClear(void) +{ + // + // Clear the clock verification. + // + HWREG(SYSCTL_CLKVCLR) = SYSCTL_CLKVCLR_CLR; + + // + // The bit does not self-reset, so clear it. + // + HWREG(SYSCTL_CLKVCLR) = 0; +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/sysctl.h b/Demo/CORTEX_LM3S811_GCC/hw_include/sysctl.h new file mode 100644 index 000000000..94b147084 --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/sysctl.h @@ -0,0 +1,285 @@ +//***************************************************************************** +// +// sysctl.h - Prototypes for the system control driver. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +#ifndef __SYSCTL_H__ +#define __SYSCTL_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// The following are values that can be passed to the +// SysCtlPeripheralPresent(), SysCtlPeripheralEnable(), +// SysCtlPeripheralDisable(), and SysCtlPeripheralReset() APIs as the +// ulPeripheral parameter. The peripherals in the fourth group (upper nibble +// is 3) can only be used with the SysCtlPeripheralPresent() API. +// +//***************************************************************************** +#define SYSCTL_PERIPH_PWM 0x00100000 // PWM +#define SYSCTL_PERIPH_ADC 0x00010000 // ADC +#define SYSCTL_PERIPH_WDOG 0x00000008 // Watchdog +#define SYSCTL_PERIPH_UART0 0x10000001 // UART 0 +#define SYSCTL_PERIPH_UART1 0x10000002 // UART 1 +#define SYSCTL_PERIPH_SSI 0x10000010 // SSI +#define SYSCTL_PERIPH_QEI 0x10000100 // QEI +#define SYSCTL_PERIPH_I2C 0x10001000 // I2C +#define SYSCTL_PERIPH_TIMER0 0x10010000 // Timer 0 +#define SYSCTL_PERIPH_TIMER1 0x10020000 // Timer 1 +#define SYSCTL_PERIPH_TIMER2 0x10040000 // Timer 2 +#define SYSCTL_PERIPH_COMP0 0x11000000 // Analog comparator 0 +#define SYSCTL_PERIPH_COMP1 0x12000000 // Analog comparator 1 +#define SYSCTL_PERIPH_COMP2 0x14000000 // Analog comparator 2 +#define SYSCTL_PERIPH_GPIOA 0x20000001 // GPIO A +#define SYSCTL_PERIPH_GPIOB 0x20000002 // GPIO B +#define SYSCTL_PERIPH_GPIOC 0x20000004 // GPIO C +#define SYSCTL_PERIPH_GPIOD 0x20000008 // GPIO D +#define SYSCTL_PERIPH_GPIOE 0x20000010 // GPIO E +#define SYSCTL_PERIPH_MPU 0x30000080 // Cortex M3 MPU +#define SYSCTL_PERIPH_TEMP 0x30000020 // Temperature sensor +#define SYSCTL_PERIPH_PLL 0x30000010 // PLL + +//***************************************************************************** +// +// The following are values that can be passed to the SysCtlPinPresent() API +// as the ulPin parameter. +// +//***************************************************************************** +#define SYSCTL_PIN_PWM0 0x00000001 // PWM0 pin +#define SYSCTL_PIN_PWM1 0x00000002 // PWM1 pin +#define SYSCTL_PIN_PWM2 0x00000004 // PWM2 pin +#define SYSCTL_PIN_PWM3 0x00000008 // PWM3 pin +#define SYSCTL_PIN_PWM4 0x00000010 // PWM4 pin +#define SYSCTL_PIN_PWM5 0x00000020 // PWM5 pin +#define SYSCTL_PIN_C0MINUS 0x00000040 // C0- pin +#define SYSCTL_PIN_C0PLUS 0x00000080 // C0+ pin +#define SYSCTL_PIN_C0O 0x00000100 // C0o pin +#define SYSCTL_PIN_C1MINUS 0x00000200 // C1- pin +#define SYSCTL_PIN_C1PLUS 0x00000400 // C1+ pin +#define SYSCTL_PIN_C1O 0x00000800 // C1o pin +#define SYSCTL_PIN_C2MINUS 0x00001000 // C2- pin +#define SYSCTL_PIN_C2PLUS 0x00002000 // C2+ pin +#define SYSCTL_PIN_C2O 0x00004000 // C2o pin +#define SYSCTL_PIN_ADC0 0x00010000 // ADC0 pin +#define SYSCTL_PIN_ADC1 0x00020000 // ADC1 pin +#define SYSCTL_PIN_ADC2 0x00040000 // ADC2 pin +#define SYSCTL_PIN_ADC3 0x00080000 // ADC3 pin +#define SYSCTL_PIN_ADC4 0x00100000 // ADC4 pin +#define SYSCTL_PIN_ADC5 0x00200000 // ADC5 pin +#define SYSCTL_PIN_ADC6 0x00400000 // ADC6 pin +#define SYSCTL_PIN_ADC7 0x00800000 // ADC7 pin +#define SYSCTL_PIN_CCP0 0x01000000 // CCP0 pin +#define SYSCTL_PIN_CCP1 0x02000000 // CCP1 pin +#define SYSCTL_PIN_CCP2 0x04000000 // CCP2 pin +#define SYSCTL_PIN_CCP3 0x08000000 // CCP3 pin +#define SYSCTL_PIN_CCP4 0x10000000 // CCP4 pin +#define SYSCTL_PIN_CCP5 0x20000000 // CCP5 pin +#define SYSCTL_PIN_32KHZ 0x80000000 // 32kHz pin + +//***************************************************************************** +// +// The following are values that can be passed to the SysCtlLDOSet() API as +// the ulVoltage value, or returned by the SysCtlLDOGet() API. +// +//***************************************************************************** +#define SYSCTL_LDO_2_25V 0x00000005 // LDO output of 2.25V +#define SYSCTL_LDO_2_30V 0x00000004 // LDO output of 2.30V +#define SYSCTL_LDO_2_35V 0x00000003 // LDO output of 2.35V +#define SYSCTL_LDO_2_40V 0x00000002 // LDO output of 2.40V +#define SYSCTL_LDO_2_45V 0x00000001 // LDO output of 2.45V +#define SYSCTL_LDO_2_50V 0x00000000 // LDO output of 2.50V +#define SYSCTL_LDO_2_55V 0x0000001f // LDO output of 2.55V +#define SYSCTL_LDO_2_60V 0x0000001e // LDO output of 2.60V +#define SYSCTL_LDO_2_65V 0x0000001d // LDO output of 2.65V +#define SYSCTL_LDO_2_70V 0x0000001c // LDO output of 2.70V +#define SYSCTL_LDO_2_75V 0x0000001b // LDO output of 2.75V + +//***************************************************************************** +// +// The following are values that can be passed to the SysCtlLDOConfigSet() API. +// +//***************************************************************************** +#define SYSCTL_LDOCFG_ARST 0x00000001 // Allow LDO failure to reset +#define SYSCTL_LDOCFG_NORST 0x00000000 // Do not reset on LDO failure + +//***************************************************************************** +// +// The following are values that can be passed to the SysCtlIntEnable(), +// SysCtlIntDisable(), and SysCtlIntClear() APIs, or returned in the bit mask +// by the SysCtlIntStatus() API. +// +//***************************************************************************** +#define SYSCTL_INT_PLL_LOCK 0x00000040 // PLL lock interrupt +#define SYSCTL_INT_CUR_LIMIT 0x00000020 // Current limit interrupt +#define SYSCTL_INT_IOSC_FAIL 0x00000010 // Internal oscillator failure int +#define SYSCTL_INT_MOSC_FAIL 0x00000008 // Main oscillator failure int +#define SYSCTL_INT_POR 0x00000004 // Power on reset interrupt +#define SYSCTL_INT_BOR 0x00000002 // Brown out interrupt +#define SYSCTL_INT_PLL_FAIL 0x00000001 // PLL failure interrupt + +//***************************************************************************** +// +// The following are values that can be passed to the SysCtlResetCauseClear() +// API or returned by the SysCtlResetCauseGet() API. +// +//***************************************************************************** +#define SYSCTL_CAUSE_LDO 0x00000020 // LDO power not OK reset +#define SYSCTL_CAUSE_SW 0x00000010 // Software reset +#define SYSCTL_CAUSE_WDOG 0x00000008 // Watchdog reset +#define SYSCTL_CAUSE_BOR 0x00000004 // Brown-out reset +#define SYSCTL_CAUSE_POR 0x00000002 // Power on reset +#define SYSCTL_CAUSE_EXT 0x00000001 // External reset + +//***************************************************************************** +// +// The following are values that can be passed to the SysCtlBrownOutConfigSet() +// API as the ulConfig parameter. +// +//***************************************************************************** +#define SYSCTL_BOR_RESET 0x00000002 // Reset instead of interrupting +#define SYSCTL_BOR_RESAMPLE 0x00000001 // Resample BOR before asserting + +//***************************************************************************** +// +// The following are values that can be passed to the SysCtlPWMClockSet() API +// as the ulConfig parameter, and can be returned by the SysCtlPWMClockGet() +// API. +// +//***************************************************************************** +#define SYSCTL_PWMDIV_1 0x00000000 // PWM clock is processor clock /1 +#define SYSCTL_PWMDIV_2 0x00100000 // PWM clock is processor clock /2 +#define SYSCTL_PWMDIV_4 0x00120000 // PWM clock is processor clock /4 +#define SYSCTL_PWMDIV_8 0x00140000 // PWM clock is processor clock /8 +#define SYSCTL_PWMDIV_16 0x00160000 // PWM clock is processor clock /16 +#define SYSCTL_PWMDIV_32 0x00180000 // PWM clock is processor clock /32 +#define SYSCTL_PWMDIV_64 0x001A0000 // PWM clock is processor clock /64 + +//***************************************************************************** +// +// The following are values that can be passed to the SysCtlADCSpeedSet() API +// as the ulSpeed parameter, and can be returned by the SyCtlADCSpeedGet() +// API. +// +//***************************************************************************** +#define SYSCTL_ADCSPEED_1MSPS 0x00000300 // 1,000,000 samples per second +#define SYSCTL_ADCSPEED_500KSPS 0x00000200 // 500,000 samples per second +#define SYSCTL_ADCSPEED_250KSPS 0x00000100 // 250,000 samples per second +#define SYSCTL_ADCSPEED_125KSPS 0x00000000 // 125,000 samples per second + +//***************************************************************************** +// +// The following are values that can be passed to the SysCtlClockSet() API as +// the ulConfig parameter. +// +//***************************************************************************** +#define SYSCTL_SYSDIV_1 0x07800000 // Processor clock is osc/pll /1 +#define SYSCTL_SYSDIV_2 0x00C00000 // Processor clock is osc/pll /2 +#define SYSCTL_SYSDIV_3 0x01400000 // Processor clock is osc/pll /3 +#define SYSCTL_SYSDIV_4 0x01C00000 // Processor clock is osc/pll /4 +#define SYSCTL_SYSDIV_5 0x02400000 // Processor clock is osc/pll /5 +#define SYSCTL_SYSDIV_6 0x02C00000 // Processor clock is osc/pll /6 +#define SYSCTL_SYSDIV_7 0x03400000 // Processor clock is osc/pll /7 +#define SYSCTL_SYSDIV_8 0x03C00000 // Processor clock is osc/pll /8 +#define SYSCTL_SYSDIV_9 0x04400000 // Processor clock is osc/pll /9 +#define SYSCTL_SYSDIV_10 0x04C00000 // Processor clock is osc/pll /10 +#define SYSCTL_SYSDIV_11 0x05400000 // Processor clock is osc/pll /11 +#define SYSCTL_SYSDIV_12 0x05C00000 // Processor clock is osc/pll /12 +#define SYSCTL_SYSDIV_13 0x06400000 // Processor clock is osc/pll /13 +#define SYSCTL_SYSDIV_14 0x06C00000 // Processor clock is osc/pll /14 +#define SYSCTL_SYSDIV_15 0x07400000 // Processor clock is osc/pll /15 +#define SYSCTL_SYSDIV_16 0x07C00000 // Processor clock is osc/pll /16 +#define SYSCTL_USE_PLL 0x00000000 // System clock is the PLL clock +#define SYSCTL_USE_OSC 0x00003800 // System clock is the osc clock +#define SYSCTL_XTAL_3_57MHZ 0x00000100 // External crystal is 3.579545MHz +#define SYSCTL_XTAL_3_68MHZ 0x00000140 // External crystal is 3.6864MHz +#define SYSCTL_XTAL_4MHZ 0x00000180 // External crystal is 4MHz +#define SYSCTL_XTAL_4_09MHZ 0x000001C0 // External crystal is 4.096MHz +#define SYSCTL_XTAL_4_91MHZ 0x00000200 // External crystal is 4.9152MHz +#define SYSCTL_XTAL_5MHZ 0x00000240 // External crystal is 5MHz +#define SYSCTL_XTAL_5_12MHZ 0x00000280 // External crystal is 5.12MHz +#define SYSCTL_XTAL_6MHZ 0x000002C0 // External crystal is 6MHz +#define SYSCTL_XTAL_6_14MHZ 0x00000300 // External crystal is 6.144MHz +#define SYSCTL_XTAL_7_37MHZ 0x00000340 // External crystal is 7.3728MHz +#define SYSCTL_XTAL_8MHZ 0x00000380 // External crystal is 8MHz +#define SYSCTL_XTAL_8_19MHZ 0x000003C0 // External crystal is 8.192MHz +#define SYSCTL_OSC_MAIN 0x00000000 // Oscillator source is main osc +#define SYSCTL_OSC_INT 0x00000010 // Oscillator source is int. osc +#define SYSCTL_OSC_INT4 0x00000020 // Oscillator source is int. osc /4 +#define SYSCTL_INT_OSC_DIS 0x00000002 // Disable internal oscillator +#define SYSCTL_MAIN_OSC_DIS 0x00000001 // Disable main oscillator + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** +extern unsigned long SysCtlSRAMSizeGet(void); +extern unsigned long SysCtlFlashSizeGet(void); +extern tBoolean SysCtlPinPresent(unsigned long ulPin); +extern tBoolean SysCtlPeripheralPresent(unsigned long ulPeripheral); +extern void SysCtlPeripheralReset(unsigned long ulPeripheral); +extern void SysCtlPeripheralEnable(unsigned long ulPeripheral); +extern void SysCtlPeripheralDisable(unsigned long ulPeripheral); +extern void SysCtlPeripheralSleepEnable(unsigned long ulPeripheral); +extern void SysCtlPeripheralSleepDisable(unsigned long ulPeripheral); +extern void SysCtlPeripheralDeepSleepEnable(unsigned long ulPeripheral); +extern void SysCtlPeripheralDeepSleepDisable(unsigned long ulPeripheral); +extern void SysCtlPeripheralClockGating(tBoolean bEnable); +extern void SysCtlIntRegister(void (*pfnHandler)(void)); +extern void SysCtlIntUnregister(void); +extern void SysCtlIntEnable(unsigned long ulInts); +extern void SysCtlIntDisable(unsigned long ulInts); +extern void SysCtlIntClear(unsigned long ulInts); +extern unsigned long SysCtlIntStatus(tBoolean bMasked); +extern void SysCtlLDOSet(unsigned long ulVoltage); +extern unsigned long SysCtlLDOGet(void); +extern void SysCtlLDOConfigSet(unsigned long ulConfig); +extern void SysCtlReset(void); +extern void SysCtlSleep(void); +extern void SysCtlDeepSleep(void); +extern unsigned long SysCtlResetCauseGet(void); +extern void SysCtlResetCauseClear(unsigned long ulCauses); +extern void SysCtlBrownOutConfigSet(unsigned long ulConfig, + unsigned long ulDelay); +extern void SysCtlClockSet(unsigned long ulConfig); +extern unsigned long SysCtlClockGet(void); +extern void SysCtlPWMClockSet(unsigned long ulConfig); +extern unsigned long SysCtlPWMClockGet(void); +extern void SysCtlADCSpeedSet(unsigned long ulSpeed); +extern unsigned long SysCtlADCSpeedGet(void); +extern void SysCtlIOSCVerificationSet(tBoolean bEnable); +extern void SysCtlMOSCVerificationSet(tBoolean bEnable); +extern void SysCtlPLLVerificationSet(tBoolean bEnable); +extern void SysCtlClkVerificationClear(void); + +#ifdef __cplusplus +} +#endif + +#endif // __SYSCTL_H__ diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/systick.c b/Demo/CORTEX_LM3S811_GCC/hw_include/systick.c new file mode 100644 index 000000000..382533513 --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/systick.c @@ -0,0 +1,262 @@ +//***************************************************************************** +// +// systick.c - Driver for the SysTick timer in NVIC. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +//***************************************************************************** +// +//! \addtogroup systick_api +//! @{ +// +//***************************************************************************** + +#include "../hw_ints.h" +#include "../hw_nvic.h" +#include "../hw_types.h" +#include "debug.h" +#include "interrupt.h" +#include "systick.h" + +//***************************************************************************** +// +//! Enables the SysTick counter. +//! +//! This will start the SysTick counter. If an interrupt handler has been +//! registered, it will be called when the SysTick counter rolls over. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_enable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SysTickEnable(void) +{ + // + // Enable SysTick. + // + HWREG(NVIC_ST_CTRL) |= NVIC_ST_CTRL_CLK_SRC | NVIC_ST_CTRL_ENABLE; +} +#endif + +//***************************************************************************** +// +//! Disables the SysTick counter. +//! +//! This will stop the SysTick counter. If an interrupt handler has been +//! registered, it will no longer be called until SysTick is restarted. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_disable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SysTickDisable(void) +{ + // + // Disable SysTick. + // + HWREG(NVIC_ST_CTRL) &= ~(NVIC_ST_CTRL_ENABLE); +} +#endif + +//***************************************************************************** +// +//! Registers an interrupt handler for the SysTick interrupt. +//! +//! \param pfnHandler is a pointer to the function to be called when the +//! SysTick interrupt occurs. +//! +//! This sets the handler to be called when a SysTick interrupt occurs. +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intregister) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SysTickIntRegister(void (*pfnHandler)(void)) +{ + // + // Register the interrupt handler, returning an error if an error occurs. + // + IntRegister(FAULT_SYSTICK, pfnHandler); + + // + // Enable the SysTick interrupt. + // + HWREG(NVIC_ST_CTRL) |= NVIC_ST_CTRL_INTEN; +} +#endif + +//***************************************************************************** +// +//! Unregisters the interrupt handler for the SysTick interrupt. +//! +//! This function will clear the handler to be called when a SysTick interrupt +//! occurs. +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intunregister) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SysTickIntUnregister(void) +{ + // + // Disable the SysTick interrupt. + // + HWREG(NVIC_ST_CTRL) &= ~(NVIC_ST_CTRL_INTEN); + + // + // Unregister the interrupt handler. + // + IntUnregister(FAULT_SYSTICK); +} +#endif + +//***************************************************************************** +// +//! Enables the SysTick interrupt. +//! +//! This function will enable the SysTick interrupt, allowing it to be +//! reflected to the processor. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intenable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SysTickIntEnable(void) +{ + // + // Enable the SysTick interrupt. + // + HWREG(NVIC_ST_CTRL) |= NVIC_ST_CTRL_INTEN; +} +#endif + +//***************************************************************************** +// +//! Disables the SysTick interrupt. +//! +//! This function will disable the SysTick interrupt, preventing it from being +//! reflected to the processor. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intdisable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SysTickIntDisable(void) +{ + // + // Disable the SysTick interrupt. + // + HWREG(NVIC_ST_CTRL) &= ~(NVIC_ST_CTRL_INTEN); +} +#endif + +//***************************************************************************** +// +//! Sets the period of the SysTick counter. +//! +//! \param ulPeriod is the number of clock ticks in each period of the SysTick +//! counter; must be between 1 and 16,777,216, inclusive. +//! +//! This function sets the rate at which the SysTick counter wraps; this +//! equates to the number of processor clocks between interrupts. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_periodset) || defined(BUILD_ALL) || defined(DOXYGEN) +void +SysTickPeriodSet(unsigned long ulPeriod) +{ + // + // Check the arguments. + // + ASSERT((ulPeriod > 0) && (ulPeriod <= 16777216)); + + // + // Set the period of the SysTick counter. + // + HWREG(NVIC_ST_RELOAD) = ulPeriod - 1; +} +#endif + +//***************************************************************************** +// +//! Gets the period of the SysTick counter. +//! +//! This function returns the rate at which the SysTick counter wraps; this +//! equates to the number of processor clocks between interrupts. +//! +//! \return Returns the period of the SysTick counter. +// +//***************************************************************************** +#if defined(GROUP_periodget) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +SysTickPeriodGet(void) +{ + // + // Return the period of the SysTick counter. + // + return(HWREG(NVIC_ST_RELOAD) + 1); +} +#endif + +//***************************************************************************** +// +//! Gets the current value of the SysTick counter. +//! +//! This function returns the current value of the SysTick counter; this will +//! be a value between the period - 1 and zero, inclusive. +//! +//! \return Returns the current value of the SysTick counter. +// +//***************************************************************************** +#if defined(GROUP_valueget) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +SysTickValueGet(void) +{ + // + // Return the current value of the SysTick counter. + // + return(HWREG(NVIC_ST_CURRENT)); +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/systick.h b/Demo/CORTEX_LM3S811_GCC/hw_include/systick.h new file mode 100644 index 000000000..bfddfb16f --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/systick.h @@ -0,0 +1,55 @@ +//***************************************************************************** +// +// systick.h - Prototypes for the SysTick driver. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +#ifndef __SYSTICK_H__ +#define __SYSTICK_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** +extern void SysTickEnable(void); +extern void SysTickDisable(void); +extern void SysTickIntRegister(void (*pfnHandler)(void)); +extern void SysTickIntUnregister(void); +extern void SysTickIntEnable(void); +extern void SysTickIntDisable(void); +extern void SysTickPeriodSet(unsigned long ulPeriod); +extern unsigned long SysTickPeriodGet(void); +extern unsigned long SysTickValueGet(void); + +#ifdef __cplusplus +} +#endif + +#endif // __SYSTICK_H__ diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/timer.c b/Demo/CORTEX_LM3S811_GCC/hw_include/timer.c new file mode 100644 index 000000000..46ce19a30 --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/timer.c @@ -0,0 +1,1125 @@ +//***************************************************************************** +// +// timer.c - Driver for the timer module. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +//***************************************************************************** +// +//! \addtogroup timer_api +//! @{ +// +//***************************************************************************** + +#include "../hw_ints.h" +#include "../hw_memmap.h" +#include "../hw_timer.h" +#include "../hw_types.h" +#include "debug.h" +#include "interrupt.h" +#include "timer.h" + +//***************************************************************************** +// +//! Enables the timer(s). +//! +//! \param ulBase is the base address of the timer module. +//! \param ulTimer specifies the timer(s) to enable; must be one of \b TIMER_A, +//! \b TIMER_B, or \b TIMER_BOTH. +//! +//! This will enable operation of the timer module. The timer must be +//! configured before it is enabled. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_enable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +TimerEnable(unsigned long ulBase, unsigned long ulTimer) +{ + // + // Check the arguments. + // + ASSERT((ulBase == TIMER0_BASE) || (ulBase == TIMER1_BASE) || + (ulBase == TIMER2_BASE)); + ASSERT((ulTimer == TIMER_A) || (ulTimer == TIMER_B) || + (ulTimer == TIMER_BOTH)); + + // + // Enable the timer(s) module. + // + HWREG(ulBase + TIMER_O_CTL) |= ulTimer & (TIMER_CTL_TAEN | TIMER_CTL_TBEN); +} +#endif + +//***************************************************************************** +// +//! Disables the timer(s). +//! +//! \param ulBase is the base address of the timer module. +//! \param ulTimer specifies the timer(s) to disable; must be one of +//! \b TIMER_A, \b TIMER_B, or \b TIMER_BOTH. +//! +//! This will disable operation of the timer module. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_disable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +TimerDisable(unsigned long ulBase, unsigned long ulTimer) +{ + // + // Check the arguments. + // + ASSERT((ulBase == TIMER0_BASE) || (ulBase == TIMER1_BASE) || + (ulBase == TIMER2_BASE)); + ASSERT((ulTimer == TIMER_A) || (ulTimer == TIMER_B) || + (ulTimer == TIMER_BOTH)); + + // + // Disable the timer module. + // + HWREG(ulBase + TIMER_O_CTL) &= ~(ulTimer & + (TIMER_CTL_TAEN | TIMER_CTL_TBEN)); +} +#endif + +//***************************************************************************** +// +//! Configures the timer(s). +//! +//! \param ulBase is the base address of the timer module. +//! \param ulConfig is the configuration for the timer. +//! +//! This function configures the operating mode of the timer(s). The timer +//! module is disabled before being configured, and is left in the disabled +//! state. The configuration is specified in \e ulConfig as one of the +//! following values: +//! +//! - \b TIMER_CFG_32_BIT_OS - 32-bit one shot timer +//! - \b TIMER_CFG_32_BIT_PER - 32-bit periodic timer +//! - \b TIMER_CFG_32_RTC - 32-bit real time clock timer +//! - \b TIMER_CFG_16_BIT_PAIR - Two 16-bit timers +//! +//! When configured for a pair of 16-bit timers, each timer is separately +//! configured. The first timer is configured by setting \e ulConfig to +//! the result of a logical OR operation between one of the following values +//! and \e ulConfig: +//! +//! - \b TIMER_CFG_A_ONE_SHOT - 16-bit one shot timer +//! - \b TIMER_CFG_A_PERIODIC - 16-bit periodic timer +//! - \b TIMER_CFG_A_CAP_COUNT - 16-bit edge count capture +//! - \b TIMER_CFG_A_CAP_TIME - 16-bit edge time capture +//! - \b TIMER_CFG_A_PWM - 16-bit PWM output +//! +//! Similarly, the second timer is configured by setting \e ulConfig to +//! the result of a logical OR operation between one of the corresponding +//! \b TIMER_CFG_B_* values and \e ulConfig. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_configure) || defined(BUILD_ALL) || defined(DOXYGEN) +void +TimerConfigure(unsigned long ulBase, unsigned long ulConfig) +{ + // + // Check the arguments. + // + ASSERT((ulBase == TIMER0_BASE) || (ulBase == TIMER1_BASE) || + (ulBase == TIMER2_BASE)); + ASSERT((ulConfig == TIMER_CFG_32_BIT_OS) || + (ulConfig == TIMER_CFG_32_BIT_PER) || + (ulConfig == TIMER_CFG_32_RTC) || + ((ulConfig & 0xff000000) == TIMER_CFG_16_BIT_PAIR)); + ASSERT(((ulConfig & 0xff000000) != TIMER_CFG_16_BIT_PAIR) || + ((((ulConfig & 0x000000ff) == TIMER_CFG_A_ONE_SHOT) || + ((ulConfig & 0x000000ff) == TIMER_CFG_A_PERIODIC) || + ((ulConfig & 0x000000ff) == TIMER_CFG_A_CAP_COUNT) || + ((ulConfig & 0x000000ff) == TIMER_CFG_A_CAP_TIME) || + ((ulConfig & 0x000000ff) == TIMER_CFG_A_PWM)) && + (((ulConfig & 0x0000ff00) == TIMER_CFG_B_ONE_SHOT) || + ((ulConfig & 0x0000ff00) == TIMER_CFG_B_PERIODIC) || + ((ulConfig & 0x0000ff00) == TIMER_CFG_B_CAP_COUNT) || + ((ulConfig & 0x0000ff00) == TIMER_CFG_B_CAP_TIME) || + ((ulConfig & 0x0000ff00) == TIMER_CFG_B_PWM)))); + + // + // Disable the timers. + // + HWREG(ulBase + TIMER_O_CTL) &= ~(TIMER_CTL_TAEN | TIMER_CTL_TBEN); + + // + // Set the global timer configuration. + // + HWREG(ulBase + TIMER_O_CFG) = ulConfig >> 24; + + // + // Set the configuration of the A and B timers. Note that the B timer + // configuration is ignored by the hardware in 32-bit modes. + // + HWREG(ulBase + TIMER_O_TAMR) = ulConfig & 255; + HWREG(ulBase + TIMER_O_TBMR) = (ulConfig >> 8) & 255; +} +#endif + +//***************************************************************************** +// +//! Controls the output level. +//! +//! \param ulBase is the base address of the timer module. +//! \param ulTimer specifies the timer(s) to adjust; must be one of \b TIMER_A, +//! \b TIMER_B, or \b TIMER_BOTH. +//! \param bInvert specifies the output level. +//! +//! This function sets the PWM output level for the specified timer. If the +//! parameter \e bInvert is \b true, then the timer's output will be made +//! active low; otherwise, it will be made active high. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_controllevel) || defined(BUILD_ALL) || defined(DOXYGEN) +void +TimerControlLevel(unsigned long ulBase, unsigned long ulTimer, + tBoolean bInvert) +{ + // + // Check the arguments. + // + ASSERT((ulBase == TIMER0_BASE) || (ulBase == TIMER1_BASE) || + (ulBase == TIMER2_BASE)); + ASSERT((ulTimer == TIMER_A) || (ulTimer == TIMER_B) || + (ulTimer == TIMER_BOTH)); + + // + // Set the output levels as requested. + // + ulTimer &= TIMER_CTL_TAPWML | TIMER_CTL_TBPWML; + HWREG(ulBase + TIMER_O_CTL) = (bInvert ? + (HWREG(ulBase + TIMER_O_CTL) | ulTimer) : + (HWREG(ulBase + TIMER_O_CTL) & ~(ulTimer))); +} +#endif + +//***************************************************************************** +// +//! Enables or disables the trigger output. +//! +//! \param ulBase is the base address of the timer module. +//! \param ulTimer specifies the timer to adjust; must be one of \b TIMER_A, +//! \b TIMER_B, or \b TIMER_BOTH. +//! \param bEnable specifies the desired trigger state. +//! +//! This function controls the trigger output for the specified timer. If the +//! parameter \e bEnable is \b true, then the timer's output trigger is +//! enabled; otherwise it is disabled. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_controltrigger) || defined(BUILD_ALL) || defined(DOXYGEN) +void +TimerControlTrigger(unsigned long ulBase, unsigned long ulTimer, + tBoolean bEnable) +{ + // + // Check the arguments. + // + ASSERT((ulBase == TIMER0_BASE) || (ulBase == TIMER1_BASE) || + (ulBase == TIMER2_BASE)); + ASSERT((ulTimer == TIMER_A) || (ulTimer == TIMER_B) || + (ulTimer == TIMER_BOTH)); + + // + // Set the trigger output as requested. + // + ulTimer &= TIMER_CTL_TAOTE | TIMER_CTL_TBOTE; + HWREG(ulBase + TIMER_O_CTL) = (bEnable ? + (HWREG(ulBase + TIMER_O_CTL) | ulTimer) : + (HWREG(ulBase + TIMER_O_CTL) & ~(ulTimer))); +} +#endif + +//***************************************************************************** +// +//! Controls the event type. +//! +//! \param ulBase is the base address of the timer module. +//! \param ulTimer specifies the timer(s) to be adjusted; must be one of +//! \b TIMER_A, \b TIMER_B, or \b TIMER_BOTH. +//! \param ulEvent specifies the type of event; must be one of +//! \b TIMER_EVENT_POS_EDGE, \b TIMER_EVENT_NEG_EDGE, or +//! \b TIMER_EVENT_BOTH_EDGES. +//! +//! This function sets the signal edge(s) that will trigger the timer when in +//! capture mode. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_controlevent) || defined(BUILD_ALL) || defined(DOXYGEN) +void +TimerControlEvent(unsigned long ulBase, unsigned long ulTimer, + unsigned long ulEvent) +{ + // + // Check the arguments. + // + ASSERT((ulBase == TIMER0_BASE) || (ulBase == TIMER1_BASE) || + (ulBase == TIMER2_BASE)); + ASSERT((ulTimer == TIMER_A) || (ulTimer == TIMER_B) || + (ulTimer == TIMER_BOTH)); + + // + // Set the event type. + // + ulEvent &= ulTimer & (TIMER_CTL_TAEVENT_MSK | TIMER_CTL_TBEVENT_MSK); + HWREG(ulBase + TIMER_O_CTL) = ((HWREG(ulBase + TIMER_O_CTL) & + ~(TIMER_CTL_TAEVENT_MSK | + TIMER_CTL_TBEVENT_MSK)) | ulEvent); +} +#endif + +//***************************************************************************** +// +//! Controls the stall handling. +//! +//! \param ulBase is the base address of the timer module. +//! \param ulTimer specifies the timer(s) to be adjusted; must be one of +//! \b TIMER_A, \b TIMER_B, or \b TIMER_BOTH. +//! \param bStall specifies the response to a stall signal. +//! +//! This function controls the stall response for the specified timer. If the +//! parameter \e bStall is \b true, then the timer will stop counting if the +//! processor enters debug mode; otherwise the timer will keep running while in +//! debug mode. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_controlstall) || defined(BUILD_ALL) || defined(DOXYGEN) +void +TimerControlStall(unsigned long ulBase, unsigned long ulTimer, + tBoolean bStall) +{ + // + // Check the arguments. + // + ASSERT((ulBase == TIMER0_BASE) || (ulBase == TIMER1_BASE) || + (ulBase == TIMER2_BASE)); + ASSERT((ulTimer == TIMER_A) || (ulTimer == TIMER_B) || + (ulTimer == TIMER_BOTH)); + + // + // Set the stall mode. + // + ulTimer &= TIMER_CTL_TASTALL | TIMER_CTL_TBSTALL; + HWREG(ulBase + TIMER_O_CTL) = (bStall ? + (HWREG(ulBase + TIMER_O_CTL) | ulTimer) : + (HWREG(ulBase + TIMER_O_CTL) & ~(ulTimer))); +} +#endif + +//***************************************************************************** +// +//! Enable RTC counting. +//! +//! \param ulBase is the base address of the timer module. +//! +//! This function causes the timer to start counting when in RTC mode. If not +//! configured for RTC mode, this will do nothing. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_rtcenable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +TimerRTCEnable(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT((ulBase == TIMER0_BASE) || (ulBase == TIMER1_BASE) || + (ulBase == TIMER2_BASE)); + + // + // Enable RTC counting. + // + HWREG(ulBase + TIMER_O_CTL) |= TIMER_CTL_RTCEN; +} +#endif + +//***************************************************************************** +// +//! Disable RTC counting. +//! +//! \param ulBase is the base address of the timer module. +//! +//! This function causes the timer to stop counting when in RTC mode. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_rtcdisable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +TimerRTCDisable(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT((ulBase == TIMER0_BASE) || (ulBase == TIMER1_BASE) || + (ulBase == TIMER2_BASE)); + + // + // Disable RTC counting. + // + HWREG(ulBase + TIMER_O_CTL) &= ~(TIMER_CTL_RTCEN); +} +#endif + +//***************************************************************************** +// +//! Set the timer prescale value. +//! +//! \param ulBase is the base address of the timer module. +//! \param ulTimer specifies the timer(s) to adjust; must be one of \b TIMER_A, +//! \b TIMER_B, or \b TIMER_BOTH. +//! \param ulValue is the timer prescale value; must be between 0 and 255, +//! inclusive. +//! +//! This function sets the value of the input clock prescaler. The prescaler +//! is only operational when in 16-bit mode and is used to extend the range of +//! the 16-bit timer modes. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_prescaleset) || defined(BUILD_ALL) || defined(DOXYGEN) +void +TimerPrescaleSet(unsigned long ulBase, unsigned long ulTimer, + unsigned long ulValue) +{ + // + // Check the arguments. + // + ASSERT((ulBase == TIMER0_BASE) || (ulBase == TIMER1_BASE) || + (ulBase == TIMER2_BASE)); + ASSERT((ulTimer == TIMER_A) || (ulTimer == TIMER_B) || + (ulTimer == TIMER_BOTH)); + ASSERT(ulValue < 256); + + // + // Set the timer A prescaler if requested. + // + if(ulTimer & TIMER_A) + { + HWREG(ulBase + TIMER_O_TAPR) = ulValue; + } + + // + // Set the timer B prescaler if requested. + // + if(ulTimer & TIMER_B) + { + HWREG(ulBase + TIMER_O_TBPR) = ulValue; + } +} +#endif + +//***************************************************************************** +// +//! Get the timer prescale value. +//! +//! \param ulBase is the base address of the timer module. +//! \param ulTimer specifies the timer; must be one of \b TIMER_A or +//! \b TIMER_B. +//! +//! This function gets the value of the input clock prescaler. The prescaler +//! is only operational when in 16-bit mode and is used to extend the range of +//! the 16-bit timer modes. +//! +//! \return The value of the timer prescaler. +// +//***************************************************************************** +#if defined(GROUP_prescaleget) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +TimerPrescaleGet(unsigned long ulBase, unsigned long ulTimer) +{ + // + // Check the arguments. + // + ASSERT((ulBase == TIMER0_BASE) || (ulBase == TIMER1_BASE) || + (ulBase == TIMER2_BASE)); + ASSERT((ulTimer == TIMER_A) || (ulTimer == TIMER_B) || + (ulTimer == TIMER_BOTH)); + + // + // Return the appropriate prescale value. + // + return((ulTimer == TIMER_A) ? HWREG(ulBase + TIMER_O_TAPR) : + HWREG(ulBase + TIMER_O_TBPR)); +} +#endif + +//***************************************************************************** +// +//! Set the timer prescale match value. +//! +//! \param ulBase is the base address of the timer module. +//! \param ulTimer specifies the timer(s) to adjust; must be one of \b TIMER_A, +//! \b TIMER_B, or \b TIMER_BOTH. +//! \param ulValue is the timer prescale match value; must be between 0 and +//! 255, inclusive. +//! +//! This function sets the value of the input clock prescaler match value. +//! When in a 16-bit mode that uses the counter match (edge count or PWM), the +//! prescale match effectively extends the range of the counter to 24-bits. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_prescalematchset) || defined(BUILD_ALL) || defined(DOXYGEN) +void +TimerPrescaleMatchSet(unsigned long ulBase, unsigned long ulTimer, + unsigned long ulValue) +{ + // + // Check the arguments. + // + ASSERT((ulBase == TIMER0_BASE) || (ulBase == TIMER1_BASE) || + (ulBase == TIMER2_BASE)); + ASSERT((ulTimer == TIMER_A) || (ulTimer == TIMER_B) || + (ulTimer == TIMER_BOTH)); + ASSERT(ulValue < 256); + + // + // Set the timer A prescale match if requested. + // + if(ulTimer & TIMER_A) + { + HWREG(ulBase + TIMER_O_TAPMR) = ulValue; + } + + // + // Set the timer B prescale match if requested. + // + if(ulTimer & TIMER_B) + { + HWREG(ulBase + TIMER_O_TBPMR) = ulValue; + } +} +#endif + +//***************************************************************************** +// +//! Get the timer prescale match value. +//! +//! \param ulBase is the base address of the timer module. +//! \param ulTimer specifies the timer; must be one of \b TIMER_A or +//! \b TIMER_B. +//! +//! This function gets the value of the input clock prescaler match value. +//! When in a 16-bit mode that uses the counter match (edge count or PWM), the +//! prescale match effectively extends the range of the counter to 24-bits. +//! +//! \return The value of the timer prescale match. +// +//***************************************************************************** +#if defined(GROUP_prescalematchget) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +TimerPrescaleMatchGet(unsigned long ulBase, unsigned long ulTimer) +{ + // + // Check the arguments. + // + ASSERT((ulBase == TIMER0_BASE) || (ulBase == TIMER1_BASE) || + (ulBase == TIMER2_BASE)); + ASSERT((ulTimer == TIMER_A) || (ulTimer == TIMER_B) || + (ulTimer == TIMER_BOTH)); + + // + // Return the appropriate prescale match value. + // + return((ulTimer == TIMER_A) ? HWREG(ulBase + TIMER_O_TAPMR) : + HWREG(ulBase + TIMER_O_TBPMR)); +} +#endif + +//***************************************************************************** +// +//! Sets the timer load value. +//! +//! \param ulBase is the base address of the timer module. +//! \param ulTimer specifies the timer(s) to adjust; must be one of \b TIMER_A, +//! \b TIMER_B, or \b TIMER_BOTH. Only \b TIMER_A should be used when the +//! timer is configured for 32-bit operation. +//! \param ulValue is the load value. +//! +//! This function sets the timer load value; if the timer is running then the +//! value will be immediately loaded into the timer. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_loadset) || defined(BUILD_ALL) || defined(DOXYGEN) +void +TimerLoadSet(unsigned long ulBase, unsigned long ulTimer, + unsigned long ulValue) +{ + // + // Check the arguments. + // + ASSERT((ulBase == TIMER0_BASE) || (ulBase == TIMER1_BASE) || + (ulBase == TIMER2_BASE)); + ASSERT((ulTimer == TIMER_A) || (ulTimer == TIMER_B) || + (ulTimer == TIMER_BOTH)); + + // + // Set the timer A load value if requested. + // + if(ulTimer & TIMER_A) + { + HWREG(ulBase + TIMER_O_TAILR) = ulValue; + } + + // + // Set the timer B load value if requested. + // + if(ulTimer & TIMER_B) + { + HWREG(ulBase + TIMER_O_TBILR) = ulValue; + } +} +#endif + +//***************************************************************************** +// +//! Gets the timer load value. +//! +//! \param ulBase is the base address of the timer module. +//! \param ulTimer specifies the timer; must be one of \b TIMER_A or +//! \b TIMER_B. Only \b TIMER_A should be used when the timer is configured +//! for 32-bit operation. +//! +//! This function gets the currently programmed interval load value for the +//! specified timer. +//! +//! \return Returns the load value for the timer. +// +//***************************************************************************** +#if defined(GROUP_loadget) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +TimerLoadGet(unsigned long ulBase, unsigned long ulTimer) +{ + // + // Check the arguments. + // + ASSERT((ulBase == TIMER0_BASE) || (ulBase == TIMER1_BASE) || + (ulBase == TIMER2_BASE)); + ASSERT((ulTimer == TIMER_A) || (ulTimer == TIMER_B)); + + // + // Return the appropriate load value. + // + return((ulTimer == TIMER_A) ? HWREG(ulBase + TIMER_O_TAILR) : + HWREG(ulBase + TIMER_O_TBILR)); +} +#endif + +//***************************************************************************** +// +//! Gets the current timer value. +//! +//! \param ulBase is the base address of the timer module. +//! \param ulTimer specifies the timer; must be one of \b TIMER_A or +//! \b TIMER_B. Only \b TIMER_A should be used when the timer is configured +//! for 32-bit operation. +//! +//! This function reads the current value of the specified timer. +//! +//! \return Returns the current value of the timer. +// +//***************************************************************************** +#if defined(GROUP_valueget) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +TimerValueGet(unsigned long ulBase, unsigned long ulTimer) +{ + // + // Check the arguments. + // + ASSERT((ulBase == TIMER0_BASE) || (ulBase == TIMER1_BASE) || + (ulBase == TIMER2_BASE)); + ASSERT((ulTimer == TIMER_A) || (ulTimer == TIMER_B)); + + // + // Return the appropriate timer value. + // + return((ulTimer == TIMER_A) ? HWREG(ulBase + TIMER_O_TAR) : + HWREG(ulBase + TIMER_O_TBR)); +} +#endif + +//***************************************************************************** +// +//! Sets the timer match value. +//! +//! \param ulBase is the base address of the timer module. +//! \param ulTimer specifies the timer(s) to adjust; must be one of \b TIMER_A, +//! \b TIMER_B, or \b TIMER_BOTH. Only \b TIMER_A should be used when the +//! timer is configured for 32-bit operation. +//! \param ulValue is the match value. +//! +//! This function sets the match value for a timer. This is used in capture +//! count mode to determine when to interrupt the processor and in PWM mode to +//! determine the duty cycle of the output signal. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_matchset) || defined(BUILD_ALL) || defined(DOXYGEN) +void +TimerMatchSet(unsigned long ulBase, unsigned long ulTimer, + unsigned long ulValue) +{ + // + // Check the arguments. + // + ASSERT((ulBase == TIMER0_BASE) || (ulBase == TIMER1_BASE) || + (ulBase == TIMER2_BASE)); + ASSERT((ulTimer == TIMER_A) || (ulTimer == TIMER_B) || + (ulTimer == TIMER_BOTH)); + + // + // Set the timer A match value if requested. + // + if(ulTimer & TIMER_A) + { + HWREG(ulBase + TIMER_O_TAMATCHR) = ulValue; + } + + // + // Set the timer B match value if requested. + // + if(ulTimer & TIMER_B) + { + HWREG(ulBase + TIMER_O_TBMATCHR) = ulValue; + } +} +#endif + +//***************************************************************************** +// +//! Gets the timer match value. +//! +//! \param ulBase is the base address of the timer module. +//! \param ulTimer specifies the timer; must be one of \b TIMER_A or +//! \b TIMER_B. Only \b TIMER_A should be used when the timer is configured +//! for 32-bit operation. +//! +//! This function gets the match value for the specified timer. +//! +//! \return Returns the match value for the timer. +// +//***************************************************************************** +#if defined(GROUP_matchget) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +TimerMatchGet(unsigned long ulBase, unsigned long ulTimer) +{ + // + // Check the arguments. + // + ASSERT((ulBase == TIMER0_BASE) || (ulBase == TIMER1_BASE) || + (ulBase == TIMER2_BASE)); + ASSERT((ulTimer == TIMER_A) || (ulTimer == TIMER_B)); + + // + // Return the appropriate match value. + // + return((ulTimer == TIMER_A) ? HWREG(ulBase + TIMER_O_TAMATCHR) : + HWREG(ulBase + TIMER_O_TBMATCHR)); +} +#endif + +//***************************************************************************** +// +//! Registers an interrupt handler for the timer interrupt. +//! +//! \param ulBase is the base address of the timer module. +//! \param ulTimer specifies the timer(s); must be one of \b TIMER_A, +//! \b TIMER_B, or \b TIMER_BOTH. +//! \param pfnHandler is a pointer to the function to be called when the timer +//! interrupt occurs. +//! +//! This sets the handler to be called when a timer interrupt occurs. This +//! will enable the global interrupt in the interrupt controller; specific +//! timer interrupts must be enabled via TimerIntEnable(). It is the interrupt +//! handler's responsibility to clear the interrupt source via TimerIntClear(). +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intregister) || defined(BUILD_ALL) || defined(DOXYGEN) +void +TimerIntRegister(unsigned long ulBase, unsigned long ulTimer, + void (*pfnHandler)(void)) +{ + // + // Check the arguments. + // + ASSERT((ulBase == TIMER0_BASE) || (ulBase == TIMER1_BASE) || + (ulBase == TIMER2_BASE)); + ASSERT((ulTimer == TIMER_A) || (ulTimer == TIMER_B) || + (ulTimer == TIMER_BOTH)); + + // + // Get the interrupt number for this timer module. + // + ulBase = ((ulBase == TIMER0_BASE) ? INT_TIMER0A : + ((ulBase == TIMER1_BASE) ? INT_TIMER1A : INT_TIMER2A)); + + // + // Register an interrupt handler for timer A if requested. + // + if(ulTimer & TIMER_A) + { + // + // Register the interrupt handler. + // + IntRegister(ulBase, pfnHandler); + + // + // Enable the interrupt. + // + IntEnable(ulBase); + } + + // + // Register an interrupt handler for timer B if requested. + // + if(ulTimer & TIMER_B) + { + // + // Register the interrupt handler. + // + IntRegister(ulBase + 1, pfnHandler); + + // + // Enable the interrupt. + // + IntEnable(ulBase + 1); + } +} +#endif + +//***************************************************************************** +// +//! Unregisters an interrupt handler for the timer interrupt. +//! +//! \param ulBase is the base address of the timer module. +//! \param ulTimer specifies the timer(s); must be one of \b TIMER_A, +//! \b TIMER_B, or \b TIMER_BOTH. +//! +//! This function will clear the handler to be called when a timer interrupt +//! occurs. This will also mask off the interrupt in the interrupt controller +//! so that the interrupt handler no longer is called. +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intunregister) || defined(BUILD_ALL) || defined(DOXYGEN) +void +TimerIntUnregister(unsigned long ulBase, unsigned long ulTimer) +{ + // + // Check the arguments. + // + ASSERT((ulBase == TIMER0_BASE) || (ulBase == TIMER1_BASE) || + (ulBase == TIMER2_BASE)); + ASSERT((ulTimer == TIMER_A) || (ulTimer == TIMER_B) || + (ulTimer == TIMER_BOTH)); + + // + // Get the interrupt number for this timer module. + // + ulBase = ((ulBase == TIMER0_BASE) ? INT_TIMER0A : + ((ulBase == TIMER1_BASE) ? INT_TIMER1A : INT_TIMER2A)); + + // + // Unregister the interrupt handler for timer A if requested. + // + if(ulTimer & TIMER_A) + { + // + // Disable the interrupt. + // + IntDisable(ulBase); + + // + // Unregister the interrupt handler. + // + IntUnregister(ulBase); + } + + // + // Unregister the interrupt handler for timer B if requested. + // + if(ulTimer & TIMER_B) + { + // + // Disable the interrupt. + // + IntDisable(ulBase + 1); + + // + // Unregister the interrupt handler. + // + IntUnregister(ulBase + 1); + } +} +#endif + +//***************************************************************************** +// +//! Enables individual timer interrupt sources. +//! +//! \param ulBase is the base address of the timer module. +//! \param ulIntFlags is the bit mask of the interrupt sources to be enabled. +//! +//! Enables the indicated timer interrupt sources. Only the sources that are +//! enabled can be reflected to the processor interrupt; disabled sources have +//! no effect on the processor. +//! +//! The parameter \e ulIntFlags must be the logical OR of any combination of +//! the following: +//! +//! - TIMER_CAPB_EVENT - Capture B event interrupt +//! - TIMER_CAPB_MATCH - Capture B match interrupt +//! - TIMER_TIMB_TIMEOUT - Timer B timeout interrupt +//! - TIMER_RTC_MATCH - RTC interrupt mask +//! - TIMER_CAPA_EVENT - Capture A event interrupt +//! - TIMER_CAPA_MATCH - Capture A match interrupt +//! - TIMER_TIMA_TIMEOUT - Timer A timeout interrupt +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intenable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +TimerIntEnable(unsigned long ulBase, unsigned long ulIntFlags) +{ + // + // Check the arguments. + // + ASSERT((ulBase == TIMER0_BASE) || (ulBase == TIMER1_BASE) || + (ulBase == TIMER2_BASE)); + + // + // Enable the specified interrupts. + // + HWREG(ulBase + TIMER_O_IMR) |= ulIntFlags; +} +#endif + +//***************************************************************************** +// +//! Disables individual timer interrupt sources. +//! +//! \param ulBase is the base address of the timer module. +//! \param ulIntFlags is the bit mask of the interrupt sources to be disabled. +//! +//! Disables the indicated timer interrupt sources. Only the sources that are +//! enabled can be reflected to the processor interrupt; disabled sources have +//! no effect on the processor. +//! +//! The parameter \e ulIntFlags has the same definition as the \e ulIntFlags +//! parameter to TimerIntEnable(). +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intdisable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +TimerIntDisable(unsigned long ulBase, unsigned long ulIntFlags) +{ + // + // Check the arguments. + // + ASSERT((ulBase == TIMER0_BASE) || (ulBase == TIMER1_BASE) || + (ulBase == TIMER2_BASE)); + + // + // Disable the specified interrupts. + // + HWREG(ulBase + TIMER_O_IMR) &= ~(ulIntFlags); +} +#endif + +//***************************************************************************** +// +//! Gets the current interrupt status. +//! +//! \param ulBase is the base address of the timer module. +//! \param bMasked is false if the raw interrupt status is required and true if +//! the masked interrupt status is required. +//! +//! This returns the interrupt status for the timer module. Either the raw +//! interrupt status or the status of interrupts that are allowed to reflect to +//! the processor can be returned. +//! +//! \return The current interrupt status, enumerated as a bit field of +//! values described in TimerIntEnable(). +// +//***************************************************************************** +#if defined(GROUP_intstatus) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +TimerIntStatus(unsigned long ulBase, tBoolean bMasked) +{ + // + // Check the arguments. + // + ASSERT((ulBase == TIMER0_BASE) || (ulBase == TIMER1_BASE) || + (ulBase == TIMER2_BASE)); + + // + // Return either the interrupt status or the raw interrupt status as + // requested. + // + return(bMasked ? HWREG(ulBase + TIMER_O_MIS) : + HWREG(ulBase + TIMER_O_RIS)); +} +#endif + +//***************************************************************************** +// +//! Clears timer interrupt sources. +//! +//! \param ulBase is the base address of the timer module. +//! \param ulIntFlags is a bit mask of the interrupt sources to be cleared. +//! +//! The specified timer interrupt sources are cleared, so that they no longer +//! assert. This must be done in the interrupt handler to keep it from being +//! called again immediately upon exit. +//! +//! The parameter \e ulIntFlags has the same definition as the \e ulIntFlags +//! parameter to TimerIntEnable(). +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intclear) || defined(BUILD_ALL) || defined(DOXYGEN) +void +TimerIntClear(unsigned long ulBase, unsigned long ulIntFlags) +{ + // + // Check the arguments. + // + ASSERT((ulBase == TIMER0_BASE) || (ulBase == TIMER1_BASE) || + (ulBase == TIMER2_BASE)); + + // + // Clear the requested interrupt sources. + // + HWREG(ulBase + TIMER_O_ICR) = ulIntFlags; +} +#endif + +//***************************************************************************** +// +//! Puts the timer into its reset state. +//! +//! \param ulBase is the base address of the timer module. +//! +//! The specified timer is disabled, and all its interrupts are disabled, +//! cleared, and unregistered. Then the timer registers are set to their reset +//! value. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_quiesce) || defined(BUILD_ALL) || defined(DOXYGEN) +void +TimerQuiesce(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT((ulBase == TIMER0_BASE) || (ulBase == TIMER1_BASE) || + (ulBase == TIMER2_BASE)); + + // + // Disable the timer. + // + HWREG(ulBase + TIMER_O_CTL) = TIMER_RV_CTL; + + // + // Disable all the timer interrupts. + // + HWREG(ulBase + TIMER_O_IMR) = TIMER_RV_IMR; + + // + // Clear all the timer interrupts. + // + HWREG(ulBase + TIMER_O_ICR) = 0xFFFFFFFF; + + // + // Unregister the interrupt handler. This also disables interrupts to the + // core. + // + TimerIntUnregister(ulBase, TIMER_BOTH); + + // + // Set all the registers to their reset value. + // + HWREG(ulBase + TIMER_O_CFG) = TIMER_RV_CFG; + HWREG(ulBase + TIMER_O_TAMR) = TIMER_RV_TAMR; + HWREG(ulBase + TIMER_O_TBMR) = TIMER_RV_TBMR; + HWREG(ulBase + TIMER_O_RIS) = TIMER_RV_RIS; + HWREG(ulBase + TIMER_O_MIS) = TIMER_RV_MIS; + HWREG(ulBase + TIMER_O_TAILR) = TIMER_RV_TAILR; + HWREG(ulBase + TIMER_O_TBILR) = TIMER_RV_TBILR; + HWREG(ulBase + TIMER_O_TAMATCHR) = TIMER_RV_TAMATCHR; + HWREG(ulBase + TIMER_O_TBMATCHR) = TIMER_RV_TBMATCHR; + HWREG(ulBase + TIMER_O_TAPR) = TIMER_RV_TAPR; + HWREG(ulBase + TIMER_O_TBPR) = TIMER_RV_TBPR; + HWREG(ulBase + TIMER_O_TAPMR) = TIMER_RV_TAPMR; + HWREG(ulBase + TIMER_O_TBPMR) = TIMER_RV_TBPMR; + HWREG(ulBase + TIMER_O_TAR) = TIMER_RV_TAR; + HWREG(ulBase + TIMER_O_TBR) = TIMER_RV_TBR; +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/timer.h b/Demo/CORTEX_LM3S811_GCC/hw_include/timer.h new file mode 100644 index 000000000..660c325f4 --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/timer.h @@ -0,0 +1,137 @@ +//***************************************************************************** +// +// timer.h - Prototypes for the timer module +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +#ifndef __TIMER_H__ +#define __TIMER_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// Values that can be passed to TimerConfigure as the ulConfig parameter. +// +//***************************************************************************** +#define TIMER_CFG_32_BIT_OS 0x00000001 // 32-bit one-shot timer +#define TIMER_CFG_32_BIT_PER 0x00000002 // 32-bit periodic timer +#define TIMER_CFG_32_RTC 0x01000000 // 32-bit RTC timer +#define TIMER_CFG_16_BIT_PAIR 0x04000000 // Two 16-bit timers +#define TIMER_CFG_A_ONE_SHOT 0x00000001 // Timer A one-shot timer +#define TIMER_CFG_A_PERIODIC 0x00000002 // Timer A periodic timer +#define TIMER_CFG_A_CAP_COUNT 0x00000003 // Timer A event counter +#define TIMER_CFG_A_CAP_TIME 0x00000007 // Timer A event timer +#define TIMER_CFG_A_PWM 0x0000000A // Timer A PWM output +#define TIMER_CFG_B_ONE_SHOT 0x00000100 // Timer B one-shot timer +#define TIMER_CFG_B_PERIODIC 0x00000200 // Timer B periodic timer +#define TIMER_CFG_B_CAP_COUNT 0x00000300 // Timer B event counter +#define TIMER_CFG_B_CAP_TIME 0x00000700 // Timer B event timer +#define TIMER_CFG_B_PWM 0x00000A00 // Timer B PWM output + +//***************************************************************************** +// +// Values that can be passed to TimerIntEnable, TimerIntDisable, and +// TimerIntClear as the ulIntFlags parameter, and returned from TimerIntStatus. +// +//***************************************************************************** +#define TIMER_CAPB_EVENT 0x00000400 // CaptureB event interrupt +#define TIMER_CAPB_MATCH 0x00000200 // CaptureB match interrupt +#define TIMER_TIMB_TIMEOUT 0x00000100 // TimerB time out interrupt +#define TIMER_RTC_MATCH 0x00000008 // RTC interrupt mask +#define TIMER_CAPA_EVENT 0x00000004 // CaptureA event interrupt +#define TIMER_CAPA_MATCH 0x00000002 // CaptureA match interrupt +#define TIMER_TIMA_TIMEOUT 0x00000001 // TimerA time out interrupt + +//***************************************************************************** +// +// Values that can be passed to TimerControlEvent as the ulEvent parameter. +// +//***************************************************************************** +#define TIMER_EVENT_POS_EDGE 0x00000000 // Count positive edges +#define TIMER_EVENT_NEG_EDGE 0x00000404 // Count negative edges +#define TIMER_EVENT_BOTH_EDGES 0x00000C0C // Count both edges + +//***************************************************************************** +// +// Values that can be passed to most of the timer APIs as the ulTimer +// parameter. +// +//***************************************************************************** +#define TIMER_A 0x000000ff // Timer A +#define TIMER_B 0x0000ff00 // Timer B +#define TIMER_BOTH 0x0000ffff // Timer Both + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** +extern void TimerEnable(unsigned long ulBase, unsigned long ulTimer); +extern void TimerDisable(unsigned long ulBase, unsigned long ulTimer); +extern void TimerConfigure(unsigned long ulBase, unsigned long ulConfig); +extern void TimerControlLevel(unsigned long ulBase, unsigned long ulTimer, + tBoolean bInvert); +extern void TimerControlTrigger(unsigned long ulBase, unsigned long ulTimer, + tBoolean bEnable); +extern void TimerControlEvent(unsigned long ulBase, unsigned long ulTimer, + unsigned long ulEvent); +extern void TimerControlStall(unsigned long ulBase, unsigned long ulTimer, + tBoolean bStall); +extern void TimerRTCEnable(unsigned long ulBase); +extern void TimerRTCDisable(unsigned long ulBase); +extern void TimerPrescaleSet(unsigned long ulBase, unsigned long ulTimer, + unsigned long ulValue); +extern unsigned long TimerPrescaleGet(unsigned long ulBase, + unsigned long ulTimer); +extern void TimerPrescaleMatchSet(unsigned long ulBase, unsigned long ulTimer, + unsigned long ulValue); +extern unsigned long TimerPrescaleMatchGet(unsigned long ulBase, + unsigned long ulTimer); +extern void TimerLoadSet(unsigned long ulBase, unsigned long ulTimer, + unsigned long ulValue); +extern unsigned long TimerLoadGet(unsigned long ulBase, unsigned long ulTimer); +extern unsigned long TimerValueGet(unsigned long ulBase, + unsigned long ulTimer); +extern void TimerMatchSet(unsigned long ulBase, unsigned long ulTimer, + unsigned long ulValue); +extern unsigned long TimerMatchGet(unsigned long ulBase, + unsigned long ulTimer); +extern void TimerIntRegister(unsigned long ulBase, unsigned long ulTimer, + void (*pfnHandler)(void)); +extern void TimerIntUnregister(unsigned long ulBase, unsigned long ulTimer); +extern void TimerIntEnable(unsigned long ulBase, unsigned long ulIntFlags); +extern void TimerIntDisable(unsigned long ulBase, unsigned long ulIntFlags); +extern unsigned long TimerIntStatus(unsigned long ulBase, tBoolean bMasked); +extern void TimerIntClear(unsigned long ulBase, unsigned long ulIntFlags); +extern void TimerQuiesce(unsigned long ulBase); + +#ifdef __cplusplus +} +#endif + +#endif // __TIMER_H__ diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/uart.c b/Demo/CORTEX_LM3S811_GCC/hw_include/uart.c new file mode 100644 index 000000000..cbae1b0ca --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/uart.c @@ -0,0 +1,821 @@ +//***************************************************************************** +// +// uart.c - Driver for the UART. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +//***************************************************************************** +// +//! \addtogroup uart_api +//! @{ +// +//***************************************************************************** + +#include "../hw_ints.h" +#include "../hw_memmap.h" +#include "../hw_types.h" +#include "../hw_uart.h" +#include "debug.h" +#include "interrupt.h" +#include "sysctl.h" +#include "uart.h" + +//***************************************************************************** +// +//! Sets the type of parity. +//! +//! \param ulBase is the base address of the UART port. +//! \param ulParity specifies the type of parity to use. +//! +//! Sets the type of parity to use for transmitting and expect when receiving. +//! The \e ulParity parameter must be one of \b UART_CONFIG_PAR_NONE, +//! \b UART_CONFIG_PAR_EVEN, \b UART_CONFIG_PAR_ODD, \b UART_CONFIG_PAR_ONE, +//! or \b UART_CONFIG_PAR_ZERO. The last two allow direct control of the +//! parity bit; it will always be either be one or zero based on the mode. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_paritymodeset) || defined(BUILD_ALL) || defined(DOXYGEN) +void +UARTParityModeSet(unsigned long ulBase, unsigned long ulParity) +{ + // + // Check the arguments. + // + ASSERT((ulBase == UART0_BASE) || (ulBase == UART1_BASE)); + ASSERT((ulParity == UART_CONFIG_PAR_NONE) || + (ulParity == UART_CONFIG_PAR_EVEN) || + (ulParity == UART_CONFIG_PAR_ODD) || + (ulParity == UART_CONFIG_PAR_ONE) || + (ulParity == UART_CONFIG_PAR_ZERO)); + + // + // Set the parity mode. + // + HWREG(ulBase + UART_O_LCR_H) = ((HWREG(ulBase + UART_O_LCR_H) & + ~(UART_LCR_H_SPS | UART_LCR_H_EPS | + UART_LCR_H_PEN)) | ulParity); +} +#endif + +//***************************************************************************** +// +//! Gets the type of parity currently being used. +//! +//! \param ulBase is the base address of the UART port. +//! +//! \return The current parity settings, specified as one of +//! \b UART_CONFIG_PAR_NONE, \b UART_CONFIG_PAR_EVEN, \b UART_CONFIG_PAR_ODD, +//! \b UART_CONFIG_PAR_ONE, or \b UART_CONFIG_PAR_ZERO. +// +//***************************************************************************** +#if defined(GROUP_paritymodeget) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +UARTParityModeGet(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT((ulBase == UART0_BASE) || (ulBase == UART1_BASE)); + + // + // Return the current parity setting. + // + return(HWREG(ulBase + UART_O_LCR_H) & + (UART_LCR_H_SPS | UART_LCR_H_EPS | UART_LCR_H_PEN)); +} +#endif + +//***************************************************************************** +// +//! Sets the configuration of a UART. +//! +//! \param ulBase is the base address of the UART port. +//! \param ulBaud is the desired baud rate. +//! \param ulConfig is the data format for the port (number of data bits, +//! number of stop bits, and parity). +//! +//! This function will configure the UART for operation in the specified data +//! format. The baud rate is provided in the \e ulBaud parameter and the +//! data format in the \e ulConfig parameter. +//! +//! The \e ulConfig parameter is the logical OR of three values: the number of +//! data bits, the number of stop bits, and the parity. \b UART_CONFIG_WLEN_8, +//! \b UART_CONFIG_WLEN_7, \b UART_CONFIG_WLEN_6, and \b UART_CONFIG_WLEN_5 +//! select from eight to five data bits per byte (respectively). +//! \b UART_CONFIG_STOP_ONE and \b UART_CONFIG_STOP_TWO select one or two stop +//! bits (respectively). \b UART_CONFIG_PAR_NONE, \b UART_CONFIG_PAR_EVEN, +//! \b UART_CONFIG_PAR_ODD, \b UART_CONFIG_PAR_ONE, and \b UART_CONFIG_PAR_ZERO +//! select the parity mode (no parity bit, even parity bit, odd parity bit, +//! parity bit always one, and parity bit always zero, respectively). +//! +//! The baud rate is dependent upon the system clock rate returned by +//! SysCtlClockGet(); if it does not return the correct system clock rate then +//! the baud rate will be incorrect. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_configset) || defined(BUILD_ALL) || defined(DOXYGEN) +void +UARTConfigSet(unsigned long ulBase, unsigned long ulBaud, + unsigned long ulConfig) +{ + unsigned long ulUARTClk, ulInt, ulFrac; + + // + // Check the arguments. + // + ASSERT((ulBase == UART0_BASE) || (ulBase == UART1_BASE)); + + // + // Stop the UART. + // + UARTDisable(ulBase); + + // + // Determine the UART clock rate. + // + ulUARTClk = SysCtlClockGet(); + + // + // Compute the fractional baud rate divider. + // + ulInt = ulUARTClk / (16 * ulBaud); + ulFrac = ulUARTClk % (16 * ulBaud); + ulFrac = ((((2 * ulFrac * 4) / ulBaud) + 1) / 2); + + // + // Set the baud rate. + // + HWREG(ulBase + UART_O_IBRD) = ulInt; + HWREG(ulBase + UART_O_FBRD) = ulFrac; + + // + // Set parity, data length, and number of stop bits. + // + HWREG(ulBase + UART_O_LCR_H) = ulConfig; + + // + // Clear the flags register. + // + HWREG(ulBase + UART_O_FR) = 0; + + // + // Start the UART. + // + UARTEnable(ulBase); +} +#endif + +//***************************************************************************** +// +//! Gets the current configuration of a UART. +//! +//! \param ulBase is the base address of the UART port. +//! \param pulBaud is a pointer to storage for the baud rate. +//! \param pulConfig is a pointer to storage for the data format. +//! +//! The baud rate and data format for the UART is determined. The returned +//! baud rate is the actual baud rate; it may not be the exact baud rate +//! requested or an ``official'' baud rate. The data format returned in +//! \e pulConfig is enumerated the same as the \e ulConfig parameter of +//! UARTConfigSet(). +//! +//! The baud rate is dependent upon the system clock rate returned by +//! SysCtlClockGet(); if it does not return the correct system clock rate then +//! the baud rate will be computed incorrectly. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_configget) || defined(BUILD_ALL) || defined(DOXYGEN) +void +UARTConfigGet(unsigned long ulBase, unsigned long *pulBaud, + unsigned long *pulConfig) + +{ + unsigned long ulInt, ulFrac; + + // + // Check the arguments. + // + ASSERT((ulBase == UART0_BASE) || (ulBase == UART1_BASE)); + + // + // Compute the baud rate. + // + ulInt = HWREG(ulBase + UART_O_IBRD); + ulFrac = HWREG(ulBase + UART_O_FBRD); + *pulBaud = (SysCtlClockGet() * 4) / ((64 * ulInt) + ulFrac); + + // + // Get the parity, data length, and number of stop bits. + // + *pulConfig = (HWREG(ulBase + UART_O_LCR_H) & + (UART_LCR_H_SPS | UART_LCR_H_WLEN | UART_LCR_H_STP2 | + UART_LCR_H_EPS | UART_LCR_H_PEN)); +} +#endif + +//***************************************************************************** +// +//! Enables transmitting and receiving. +//! +//! \param ulBase is the base address of the UART port. +//! +//! Sets the UARTEN, TXE, and RXE bits, and enables the transmit and receive +//! FIFOs. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_enable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +UARTEnable(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT((ulBase == UART0_BASE) || (ulBase == UART1_BASE)); + + // + // Enable the FIFO. + // + HWREG(ulBase + UART_O_LCR_H) |= UART_LCR_H_FEN; + + // + // Enable RX, TX, and the UART. + // + HWREG(ulBase + UART_O_CTL) |= (UART_CTL_UARTEN | UART_CTL_TXE | + UART_CTL_RXE); +} +#endif + +//***************************************************************************** +// +//! Disables transmitting and receiving. +//! +//! \param ulBase is the base address of the UART port. +//! +//! Clears the UARTEN, TXE, and RXE bits, then waits for the end of +//! transmission of the current character, and flushes the transmit FIFO. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_disable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +UARTDisable(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT((ulBase == UART0_BASE) || (ulBase == UART1_BASE)); + + // + // Wait for end of TX. + // + while(HWREG(ulBase + UART_O_FR) & UART_FR_BUSY) + { + } + + // + // Disable the FIFO. + // + HWREG(ulBase + UART_O_LCR_H) &= ~(UART_LCR_H_FEN); + + // + // Disable the UART. + // + HWREG(ulBase + UART_O_CTL) &= ~(UART_CTL_UARTEN | UART_CTL_TXE | + UART_CTL_RXE); +} +#endif + +//***************************************************************************** +// +//! Determines if there are any characters in the receive FIFO. +//! +//! \param ulBase is the base address of the UART port. +//! +//! This function returns a flag indicating whether or not there is data +//! available in the receive FIFO. +//! +//! \return Returns \b true if there is data in the receive FIFO, and \b false +//! if there is no data in the receive FIFO. +// +//***************************************************************************** +#if defined(GROUP_charsavail) || defined(BUILD_ALL) || defined(DOXYGEN) +tBoolean +UARTCharsAvail(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT((ulBase == UART0_BASE) || (ulBase == UART1_BASE)); + + // + // Return the availability of characters. + // + return((HWREG(ulBase + UART_O_FR) & UART_FR_RXFE) ? false : true); +} +#endif + +//***************************************************************************** +// +//! Determines if there is any space in the transmit FIFO. +//! +//! \param ulBase is the base address of the UART port. +//! +//! This function returns a flag indicating whether or not there is space +//! available in the transmit FIFO. +//! +//! \return Returns \b true if there is space available in the transmit FIFO, +//! and \b false if there is no space available in the transmit FIFO. +// +//***************************************************************************** +#if defined(GROUP_spaceavail) || defined(BUILD_ALL) || defined(DOXYGEN) +tBoolean +UARTSpaceAvail(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT((ulBase == UART0_BASE) || (ulBase == UART1_BASE)); + + // + // Return the availability of space. + // + return((HWREG(ulBase + UART_O_FR) & UART_FR_TXFF) ? false : true); +} +#endif + +//***************************************************************************** +// +//! Receives a character from the specified port. +//! +//! \param ulBase is the base address of the UART port. +//! +//! Gets a character from the receive FIFO for the specified port. +//! +//! \return Returns the character read from the specified port, cast as a +//! \e long. A \b -1 will be returned if there are no characters present in +//! the receive FIFO. The UARTCharsAvail() function should be called before +//! attempting to call this function. +// +//***************************************************************************** +#if defined(GROUP_charnonblockingget) || defined(BUILD_ALL) || defined(DOXYGEN) +long +UARTCharNonBlockingGet(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT((ulBase == UART0_BASE) || (ulBase == UART1_BASE)); + + // + // See if there are any characters in the receive FIFO. + // + if(!(HWREG(ulBase + UART_O_FR) & UART_FR_RXFE)) + { + // + // Read and return the next character. + // + return(HWREG(ulBase + UART_O_DR)); + } + else + { + // + // There are no characters, so return a failure. + // + return(-1); + } +} +#endif + +//***************************************************************************** +// +//! Waits for a character from the specified port. +//! +//! \param ulBase is the base address of the UART port. +//! +//! Gets a character from the receive FIFO for the specified port. If there +//! are no characters available, this function will wait until a character is +//! received before returning. +//! +//! \return Returns the character read from the specified port, cast as an +//! \e int. +// +//***************************************************************************** +#if defined(GROUP_charget) || defined(BUILD_ALL) || defined(DOXYGEN) +long +UARTCharGet(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT((ulBase == UART0_BASE) || (ulBase == UART1_BASE)); + + // + // Wait until a char is available. + // + while(HWREG(ulBase + UART_O_FR) & UART_FR_RXFE) + { + } + + // + // Now get the char. + // + return(HWREG(ulBase + UART_O_DR)); +} +#endif + +//***************************************************************************** +// +//! Sends a character to the specified port. +//! +//! \param ulBase is the base address of the UART port. +//! \param ucData is the character to be transmitted. +//! +//! Writes the character \e ucData to the transmit FIFO for the specified port. +//! This function does not block, so if there is no space available, then a +//! \b false is returned, and the application will have to retry the function +//! later. +//! +//! \return Returns \b true if the character was successfully placed in the +//! transmit FIFO, and \b false if there was no space available in the transmit +//! FIFO. +// +//***************************************************************************** +#if defined(GROUP_charnonblockingput) || defined(BUILD_ALL) || defined(DOXYGEN) +tBoolean +UARTCharNonBlockingPut(unsigned long ulBase, unsigned char ucData) +{ + // + // Check the arguments. + // + ASSERT((ulBase == UART0_BASE) || (ulBase == UART1_BASE)); + + // + // See if there is space in the transmit FIFO. + // + if(!(HWREG(ulBase + UART_O_FR) & UART_FR_TXFF)) + { + // + // Write this character to the transmit FIFO. + // + HWREG(ulBase + UART_O_DR) = ucData; + + // + // Success. + // + return(true); + } + else + { + // + // There is no space in the transmit FIFO, so return a failure. + // + return(false); + } +} +#endif + +//***************************************************************************** +// +//! Waits to send a character from the specified port. +//! +//! \param ulBase is the base address of the UART port. +//! \param ucData is the character to be transmitted. +//! +//! Sends the character \e ucData to the transmit FIFO for the specified port. +//! If there is no space available in the transmit FIFO, this function will +//! wait until there is space available before returning. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_charput) || defined(BUILD_ALL) || defined(DOXYGEN) +void +UARTCharPut(unsigned long ulBase, unsigned char ucData) +{ + // + // Check the arguments. + // + ASSERT((ulBase == UART0_BASE) || (ulBase == UART1_BASE)); + + // + // Wait until space is available. + // + while(HWREG(ulBase + UART_O_FR) & UART_FR_TXFF) + { + } + + // + // Send the char. + // + HWREG(ulBase + UART_O_DR) = ucData; +} +#endif + +//***************************************************************************** +// +//! Causes a BREAK to be sent. +//! +//! \param ulBase is the base address of the UART port. +//! \param bBreakState controls the output level. +//! +//! Calling this function with \e bBreakState set to \b true will assert a +//! break condition on the UART. Calling this function with \e bBreakState set +//! to \b false will remove the break condition. For proper transmission of a +//! break command, the break must be asserted for at least two complete frames. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_breakctl) || defined(BUILD_ALL) || defined(DOXYGEN) +void +UARTBreakCtl(unsigned long ulBase, tBoolean bBreakState) +{ + // + // Check the arguments. + // + ASSERT((ulBase == UART0_BASE) || (ulBase == UART1_BASE)); + + // + // Set the break condition as requested. + // + HWREG(ulBase + UART_O_LCR_H) = + (bBreakState ? + (HWREG(ulBase + UART_O_LCR_H) | UART_LCR_H_BRK) : + (HWREG(ulBase + UART_O_LCR_H) & ~(UART_LCR_H_BRK))); +} +#endif + +//***************************************************************************** +// +//! Registers an interrupt handler for a UART interrupt. +//! +//! \param ulBase is the base address of the UART port. +//! \param pfnHandler is a pointer to the function to be called when the +//! UART interrupt occurs. +//! +//! This function does the actual registering of the interrupt handler. This +//! will enable the global interrupt in the interrupt controller; specific UART +//! interrupts must be enabled via UARTIntEnable(). It is the interrupt +//! handler's responsibility to clear the interrupt source. +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intregister) || defined(BUILD_ALL) || defined(DOXYGEN) +void +UARTIntRegister(unsigned long ulBase, void (*pfnHandler)(void)) +{ + unsigned long ulInt; + + // + // Check the arguments. + // + ASSERT((ulBase == UART0_BASE) || (ulBase == UART1_BASE)); + + // + // Determine the interrupt number based on the UART port. + // + ulInt = (ulBase == UART0_BASE) ? INT_UART0 : INT_UART1; + + // + // Register the interrupt handler. + // + IntRegister(ulInt, pfnHandler); + + // + // Enable the UART interrupt. + // + IntEnable(ulInt); +} +#endif + +//***************************************************************************** +// +//! Unregisters an interrupt handler for a UART interrupt. +//! +//! \param ulBase is the base address of the UART port. +//! +//! This function does the actual unregistering of the interrupt handler. It +//! will clear the handler to be called when a UART interrupt occurs. This +//! will also mask off the interrupt in the interrupt controller so that the +//! interrupt handler no longer is called. +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intunregister) || defined(BUILD_ALL) || defined(DOXYGEN) +void +UARTIntUnregister(unsigned long ulBase) +{ + unsigned long ulInt; + + // + // Check the arguments. + // + ASSERT((ulBase == UART0_BASE) || (ulBase == UART1_BASE)); + + // + // Determine the interrupt number based on the UART port. + // + ulInt = (ulBase == UART0_BASE) ? INT_UART0 : INT_UART1; + + // + // Disable the interrupt. + // + IntDisable(ulInt); + + // + // Unregister the interrupt handler. + // + IntUnregister(ulInt); +} +#endif + +//***************************************************************************** +// +//! Enables individual UART interrupt sources. +//! +//! \param ulBase is the base address of the UART port. +//! \param ulIntFlags is the bit mask of the interrupt sources to be enabled. +//! +//! Enables the indicated UART interrupt sources. Only the sources that are +//! enabled can be reflected to the processor interrupt; disabled sources have +//! no effect on the processor. +//! +//! The parameter \e ulIntFlags is the logical OR of any of the following: +//! +//! - UART_INT_OE - Overrun Error interrupt +//! - UART_INT_BE - Break Error interrupt +//! - UART_INT_PE - Parity Error interrupt +//! - UART_INT_FE - Framing Error interrupt +//! - UART_INT_RT - Receive Timeout interrupt +//! - UART_INT_TX - Transmit interrupt +//! - UART_INT_RX - Receive interrupt +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intenable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +UARTIntEnable(unsigned long ulBase, unsigned long ulIntFlags) +{ + // + // Check the arguments. + // + ASSERT((ulBase == UART0_BASE) || (ulBase == UART1_BASE)); + + // + // Enable the specified interrupts. + // + HWREG(ulBase + UART_O_IM) |= ulIntFlags; +} +#endif + +//***************************************************************************** +// +//! Disables individual UART interrupt sources. +//! +//! \param ulBase is the base address of the UART port. +//! \param ulIntFlags is the bit mask of the interrupt sources to be disabled. +//! +//! Disables the indicated UART interrupt sources. Only the sources that are +//! enabled can be reflected to the processor interrupt; disabled sources have +//! no effect on the processor. +//! +//! The parameter \e ulIntFlags has the same definition as the same parameter +//! to UARTIntEnable(). +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intdisable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +UARTIntDisable(unsigned long ulBase, unsigned long ulIntFlags) +{ + // + // Check the arguments. + // + ASSERT((ulBase == UART0_BASE) || (ulBase == UART1_BASE)); + + // + // Disable the specified interrupts. + // + HWREG(ulBase + UART_O_IM) &= ~(ulIntFlags); +} +#endif + +//***************************************************************************** +// +//! Gets the current interrupt status. +//! +//! \param ulBase is the base address of the UART port. +//! \param bMasked is false if the raw interrupt status is required and true +//! if the masked interrupt status is required. +//! +//! This returns the interrupt status for the specified UART. Either the raw +//! interrupt status or the status of interrupts that are allowed to reflect to +//! the processor can be returned. +//! +//! \return The current interrupt status, enumerated as a bit field of +//! values described in UARTIntEnable(). +// +//***************************************************************************** +#if defined(GROUP_intstatus) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +UARTIntStatus(unsigned long ulBase, tBoolean bMasked) +{ + // + // Check the arguments. + // + ASSERT((ulBase == UART0_BASE) || (ulBase == UART1_BASE)); + + // + // Return either the interrupt status or the raw interrupt status as + // requested. + // + if(bMasked) + { + return(HWREG(ulBase + UART_O_MIS)); + } + else + { + return(HWREG(ulBase + UART_O_RIS)); + } +} +#endif + +//***************************************************************************** +// +//! Clears UART interrupt sources. +//! +//! \param ulBase is the base address of the UART port. +//! \param ulIntFlags is a bit mask of the interrupt sources to be cleared. +//! +//! The specified UART interrupt sources are cleared, so that they no longer +//! assert. This must be done in the interrupt handler to keep it from being +//! called again immediately upon exit. +//! +//! The parameter \e ulIntFlags has the same definition as the same parameter +//! to UARTIntEnable(). +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intclear) || defined(BUILD_ALL) || defined(DOXYGEN) +void +UARTIntClear(unsigned long ulBase, unsigned long ulIntFlags) +{ + // + // Check the arguments. + // + ASSERT((ulBase == UART0_BASE) || (ulBase == UART1_BASE)); + + // + // Clear the requested interrupt sources. + // + HWREG(ulBase + UART_O_ICR) = ulIntFlags; +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/uart.h b/Demo/CORTEX_LM3S811_GCC/hw_include/uart.h new file mode 100644 index 000000000..b82f2eec5 --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/uart.h @@ -0,0 +1,102 @@ +//***************************************************************************** +// +// uart.h - Defines and Macros for the UART. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +#ifndef __UART_H__ +#define __UART_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// Values that can be passed to UARTIntEnable, UARTIntDisable, and UARTIntClear +// as the ulIntFlags parameter, and returned from UARTIntStatus. +// +//***************************************************************************** +#define UART_INT_OE 0x400 // Overrun Error Interrupt Mask +#define UART_INT_BE 0x200 // Break Error Interrupt Mask +#define UART_INT_PE 0x100 // Parity Error Interrupt Mask +#define UART_INT_FE 0x080 // Framing Error Interrupt Mask +#define UART_INT_RT 0x040 // Receive Timeout Interrupt Mask +#define UART_INT_TX 0x020 // Transmit Interrupt Mask +#define UART_INT_RX 0x010 // Receive Interrupt Mask + +//***************************************************************************** +// +// Values that can be passed to UARTConfigSet as the ulConfig parameter and +// returned by UARTConfigGet in the pulConfig parameter. Additionally, the +// UART_CONFIG_PAR_* subset can be passed to UARTParityModeSet as the ulParity +// parameter, and are returned by UARTParityModeGet. +// +//***************************************************************************** +#define UART_CONFIG_WLEN_8 0x00000060 // 8 bit data +#define UART_CONFIG_WLEN_7 0x00000040 // 7 bit data +#define UART_CONFIG_WLEN_6 0x00000020 // 6 bit data +#define UART_CONFIG_WLEN_5 0x00000000 // 5 bit data +#define UART_CONFIG_STOP_ONE 0x00000000 // One stop bit +#define UART_CONFIG_STOP_TWO 0x00000008 // Two stop bits +#define UART_CONFIG_PAR_NONE 0x00000000 // No parity +#define UART_CONFIG_PAR_EVEN 0x00000006 // Even parity +#define UART_CONFIG_PAR_ODD 0x00000002 // Odd parity +#define UART_CONFIG_PAR_ONE 0x00000086 // Parity bit is one +#define UART_CONFIG_PAR_ZERO 0x00000082 // Parity bit is zero + +//***************************************************************************** +// +// API Function prototypes +// +//***************************************************************************** +extern void UARTParityModeSet(unsigned long ulBase, unsigned long ulParity); +extern unsigned long UARTParityModeGet(unsigned long ulBase); +extern void UARTConfigSet(unsigned long ulBase, unsigned long ulBaud, + unsigned long ulConfig); +extern void UARTConfigGet(unsigned long ulBase, unsigned long *pulBaud, + unsigned long *pulConfig); +extern void UARTEnable(unsigned long ulBase); +extern void UARTDisable(unsigned long ulBase); +extern tBoolean UARTCharsAvail(unsigned long ulBase); +extern tBoolean UARTSpaceAvail(unsigned long ulBase); +extern long UARTCharNonBlockingGet(unsigned long ulBase); +extern long UARTCharGet(unsigned long ulBase); +extern tBoolean UARTCharNonBlockingPut(unsigned long ulBase, + unsigned char ucData); +extern void UARTCharPut(unsigned long ulBase, unsigned char ucData); +extern void UARTBreakCtl(unsigned long ulBase, tBoolean bBreakState); +extern void UARTIntRegister(unsigned long ulBase, void(*pfnHandler)(void)); +extern void UARTIntUnregister(unsigned long ulBase); +extern void UARTIntEnable(unsigned long ulBase, unsigned long ulIntFlags); +extern void UARTIntDisable(unsigned long ulBase, unsigned long ulIntFlags); +extern unsigned long UARTIntStatus(unsigned long ulBase, tBoolean bMasked); +extern void UARTIntClear(unsigned long ulBase, unsigned long ulIntFlags); + +#ifdef __cplusplus +} +#endif + +#endif // __UART_H__ diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/watchdog.c b/Demo/CORTEX_LM3S811_GCC/hw_include/watchdog.c new file mode 100644 index 000000000..53332d051 --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/watchdog.c @@ -0,0 +1,592 @@ +//***************************************************************************** +// +// watchdog.c - Driver for the Watchdog Timer Module. +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +//***************************************************************************** +// +//! \addtogroup watchdog_api +//! @{ +// +//***************************************************************************** + +#include "../hw_ints.h" +#include "../hw_memmap.h" +#include "../hw_types.h" +#include "../hw_watchdog.h" +#include "debug.h" +#include "interrupt.h" +#include "watchdog.h" + +//***************************************************************************** +// +//! Determines if the watchdog timer is enabled. +//! +//! \param ulBase is the base address of the watchdog timer module. +//! +//! This will check to see if the watchdog timer is enabled. +//! +//! \return Returns \b true if the watchdog timer is enabled, and \b false +//! if it is not. +// +//***************************************************************************** +#if defined(GROUP_running) || defined(BUILD_ALL) || defined(DOXYGEN) +tBoolean +WatchdogRunning(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == WATCHDOG_BASE); + + // + // See if the watchdog timer module is enabled, and return. + // + return(HWREG(ulBase + WDT_O_CTL) & WDT_CTL_INTEN); +} +#endif + +//***************************************************************************** +// +//! Enables the watchdog timer. +//! +//! \param ulBase is the base address of the watchdog timer module. +//! +//! This will enable the watchdog timer counter and interrupt. +//! +//! \note This function will have no effect if the watchdog timer has +//! been locked. +//! +//! \sa WatchdogLock(), WatchdogUnlock() +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_enable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +WatchdogEnable(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == WATCHDOG_BASE); + + // + // Enable the watchdog timer module. + // + HWREG(ulBase + WDT_O_CTL) |= WDT_CTL_INTEN; +} +#endif + +//***************************************************************************** +// +//! Enables the watchdog timer reset. +//! +//! \param ulBase is the base address of the watchdog timer module. +//! +//! Enables the capability of the watchdog timer to issue a reset to the +//! processor upon a second timeout condition. +//! +//! \note This function will have no effect if the watchdog timer has +//! been locked. +//! +//! \sa WatchdogLock(), WatchdogUnlock() +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_resetenable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +WatchdogResetEnable(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == WATCHDOG_BASE); + + // + // Enable the watchdog reset. + // + HWREG(ulBase + WDT_O_CTL) |= WDT_CTL_RESEN; +} +#endif + +//***************************************************************************** +// +//! Disables the watchdog timer reset. +//! +//! \param ulBase is the base address of the watchdog timer module. +//! +//! Disables the capability of the watchdog timer to issue a reset to the +//! processor upon a second timeout condition. +//! +//! \note This function will have no effect if the watchdog timer has +//! been locked. +//! +//! \sa WatchdogLock(), WatchdogUnlock() +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_resetdisable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +WatchdogResetDisable(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == WATCHDOG_BASE); + + // + // Disable the watchdog reset. + // + HWREG(ulBase + WDT_O_CTL) &= ~(WDT_CTL_RESEN); +} +#endif + +//***************************************************************************** +// +//! Enables the watchdog timer lock mechanism. +//! +//! \param ulBase is the base address of the watchdog timer module. +//! +//! Locks out write access to the watchdog timer configuration registers. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_lock) || defined(BUILD_ALL) || defined(DOXYGEN) +void +WatchdogLock(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == WATCHDOG_BASE); + + // + // Lock out watchdog register writes. Writing anything to the WDT_O_LOCK + // register causes the lock to go into effect. + // + HWREG(ulBase + WDT_O_LOCK) = WDT_LOCK_LOCKED; +} +#endif + +//***************************************************************************** +// +//! Disables the watchdog timer lock mechanism. +//! +//! \param ulBase is the base address of the watchdog timer module. +//! +//! Enables write access to the watchdog timer configuration registers. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_unlock) || defined(BUILD_ALL) || defined(DOXYGEN) +void +WatchdogUnlock(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == WATCHDOG_BASE); + + // + // Unlock watchdog register writes. + // + HWREG(ulBase + WDT_O_LOCK) = WDT_LOCK_UNLOCK; +} +#endif + +//***************************************************************************** +// +//! Gets the state of the watchdog timer lock mechanism. +//! +//! \param ulBase is the base address of the watchdog timer module. +//! +//! Returns the lock state of the watchdog timer registers. +//! +//! \return Returns \b true if the watchdog timer registers are locked, and +//! \b false if they are not locked. +// +//***************************************************************************** +#if defined(GROUP_lockstate) || defined(BUILD_ALL) || defined(DOXYGEN) +tBoolean +WatchdogLockState(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == WATCHDOG_BASE); + + // + // Get the lock state. + // + return((HWREG(ulBase + WDT_O_LOCK) == WDT_LOCK_LOCKED) ? true : false); +} +#endif + +//***************************************************************************** +// +//! Sets the watchdog timer reload value. +//! +//! \param ulBase is the base address of the watchdog timer module. +//! \param ulLoadVal is the load value for the watchdog timer. +//! +//! This function sets the value to load into the watchdog timer when the count +//! reaches zero for the first time; if the watchdog timer is running when this +//! function is called, then the value will be immediately loaded into the +//! watchdog timer counter. If the parameter \e ulLoadVal is 0, then an +//! interrupt is immediately generated. +//! +//! \note This function will have no effect if the watchdog timer has +//! been locked. +//! +//! \sa WatchdogLock(), WatchdogUnlock(), WatchdogReloadGet() +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_reloadset) || defined(BUILD_ALL) || defined(DOXYGEN) +void +WatchdogReloadSet(unsigned long ulBase, unsigned long ulLoadVal) +{ + // + // Check the arguments. + // + ASSERT(ulBase == WATCHDOG_BASE); + + // + // Set the load register. + // + HWREG(ulBase + WDT_O_LOAD) = ulLoadVal; +} +#endif + +//***************************************************************************** +// +//! Gets the watchdog timer reload value. +//! +//! \param ulBase is the base address of the watchdog timer module. +//! +//! This function gets the value that is loaded into the watchdog timer when +//! the count reaches zero for the first time. +//! +//! \sa WatchdogReloadSet() +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_reloadget) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +WatchdogReloadGet(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == WATCHDOG_BASE); + + // + // Get the load register. + // + return(HWREG(ulBase + WDT_O_LOAD)); +} +#endif + +//***************************************************************************** +// +//! Gets the current watchdog timer value. +//! +//! \param ulBase is the base address of the watchdog timer module. +//! +//! This function reads the current value of the watchdog timer. +//! +//! \return Returns the current value of the watchdog timer. +// +//***************************************************************************** +#if defined(GROUP_valueget) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +WatchdogValueGet(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == WATCHDOG_BASE); + + // + // Get the current watchdog timer register value. + // + return(HWREG(ulBase + WDT_O_VALUE)); +} +#endif + +//***************************************************************************** +// +//! Registers an interrupt handler for watchdog timer interrupt. +//! +//! \param ulBase is the base address of the watchdog timer module. +//! \param pfnHandler is a pointer to the function to be called when the +//! watchdog timer interrupt occurs. +//! +//! This function does the actual registering of the interrupt handler. This +//! will enable the global interrupt in the interrupt controller; the watchdog +//! timer interrupt must be enabled via WatchdogEnable(). It is the interrupt +//! handler's responsibility to clear the interrupt source via +//! WatchdogIntClear(). +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intregister) || defined(BUILD_ALL) || defined(DOXYGEN) +void +WatchdogIntRegister(unsigned long ulBase, void (*pfnHandler)(void)) +{ + // + // Check the arguments. + // + ASSERT(ulBase == WATCHDOG_BASE); + + // + // Register the interrupt handler. + // + IntRegister(INT_WATCHDOG, pfnHandler); + + // + // Enable the watchdog timer interrupt. + // + IntEnable(INT_WATCHDOG); +} +#endif + +//***************************************************************************** +// +//! Unregisters an interrupt handler for the watchdog timer interrupt. +//! +//! \param ulBase is the base address of the watchdog timer module. +//! +//! This function does the actual unregistering of the interrupt handler. This +//! function will clear the handler to be called when a watchdog timer +//! interrupt occurs. This will also mask off the interrupt in the interrupt +//! controller so that the interrupt handler no longer is called. +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intunregister) || defined(BUILD_ALL) || defined(DOXYGEN) +void +WatchdogIntUnregister(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == WATCHDOG_BASE); + + // + // Disable the interrupt. + // + IntDisable(INT_WATCHDOG); + + // + // Unregister the interrupt handler. + // + IntUnregister(INT_WATCHDOG); +} +#endif + +//***************************************************************************** +// +//! Enables the watchdog timer interrupt. +//! +//! \param ulBase is the base address of the watchdog timer module. +//! +//! Enables the watchdog timer interrupt. +//! +//! \note This function will have no effect if the watchdog timer has +//! been locked. +//! +//! \sa WatchdogLock(), WatchdogUnlock(), WatchdogEnable() +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intenable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +WatchdogIntEnable(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == WATCHDOG_BASE); + + // + // Enable the watchdog interrupt. + // + HWREG(ulBase + WDT_O_CTL) |= WDT_CTL_INTEN; +} +#endif + +//***************************************************************************** +// +//! Gets the current watchdog timer interrupt status. +//! +//! \param ulBase is the base address of the watchdog timer module. +//! \param bMasked is \b false if the raw interrupt status is required and +//! \b true if the masked interrupt status is required. +//! +//! This returns the interrupt status for the watchdog timer module. Either +//! the raw interrupt status or the status of interrupt that is allowed to +//! reflect to the processor can be returned. +//! +//! \return The current interrupt status, where a 1 indicates that the watchdog +//! interrupt is active, and a 0 indicates that it is not active. +// +//***************************************************************************** +#if defined(GROUP_intstatus) || defined(BUILD_ALL) || defined(DOXYGEN) +unsigned long +WatchdogIntStatus(unsigned long ulBase, tBoolean bMasked) +{ + // + // Check the arguments. + // + ASSERT(ulBase == WATCHDOG_BASE); + + // + // Return either the interrupt status or the raw interrupt status as + // requested. + // + if(bMasked) + { + return(HWREG(ulBase + WDT_O_MIS)); + } + else + { + return(HWREG(ulBase + WDT_O_RIS)); + } +} +#endif + +//***************************************************************************** +// +//! Clears the watchdog timer interrupt. +//! +//! \param ulBase is the base address of the watchdog timer module. +//! +//! The watchdog timer interrupt source is cleared, so that it no longer +//! asserts. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_intclear) || defined(BUILD_ALL) || defined(DOXYGEN) +void +WatchdogIntClear(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == WATCHDOG_BASE); + + // + // Clear the interrupt source. + // + HWREG(ulBase + WDT_O_ICR) = WDT_INT_TIMEOUT; +} +#endif + +//***************************************************************************** +// +//! Enables stalling of the watchdog timer during debug events. +//! +//! \param ulBase is the base address of the watchdog timer module. +//! +//! This function allows the watchdog timer to stop counting when the processor +//! is stopped by the debugger. By doing so, the watchdog is prevented from +//! expiring (typically almost immediately from a human time perspective) and +//! resetting the system (if reset is enabled). The watchdog will instead +//! expired after the appropriate number of processor cycles have been executed +//! while debugging (or at the appropriate time after the processor has been +//! restarted). +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_stallenable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +WatchdogStallEnable(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == WATCHDOG_BASE); + + // + // Enable timer stalling. + // + HWREG(ulBase + WDT_O_TEST) |= WDT_TEST_STALL; +} +#endif + +//***************************************************************************** +// +//! Disables stalling of the watchdog timer during debug events. +//! +//! \param ulBase is the base address of the watchdog timer module. +//! +//! This function disables the debug mode stall of the watchdog timer. By +//! doing so, the watchdog timer continues to count regardless of the processor +//! debug state. +//! +//! \return None. +// +//***************************************************************************** +#if defined(GROUP_stalldisable) || defined(BUILD_ALL) || defined(DOXYGEN) +void +WatchdogStallDisable(unsigned long ulBase) +{ + // + // Check the arguments. + // + ASSERT(ulBase == WATCHDOG_BASE); + + // + // Disable timer stalling. + // + HWREG(ulBase + WDT_O_TEST) &= ~(WDT_TEST_STALL); +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/Demo/CORTEX_LM3S811_GCC/hw_include/watchdog.h b/Demo/CORTEX_LM3S811_GCC/hw_include/watchdog.h new file mode 100644 index 000000000..9378504a0 --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/hw_include/watchdog.h @@ -0,0 +1,63 @@ +//***************************************************************************** +// +// watchdog.h - Prototypes for the Watchdog Timer API +// +// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's Stellaris Family of microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 991 of the Stellaris Driver Library. +// +//***************************************************************************** + +#ifndef __WATCHDOG_H__ +#define __WATCHDOG_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** +extern tBoolean WatchdogRunning(unsigned long ulBase); +extern void WatchdogEnable(unsigned long ulBase); +extern void WatchdogResetEnable(unsigned long ulBase); +extern void WatchdogResetDisable(unsigned long ulBase); +extern void WatchdogLock(unsigned long ulBase); +extern void WatchdogUnlock(unsigned long ulBase); +extern tBoolean WatchdogLockState(unsigned long ulBase); +extern void WatchdogReloadSet(unsigned long ulBase, unsigned long ulLoadVal); +extern unsigned long WatchdogReloadGet(unsigned long ulBase); +extern unsigned long WatchdogValueGet(unsigned long ulBase); +extern void WatchdogIntRegister(unsigned long ulBase, void(*pfnHandler)(void)); +extern void WatchdogIntUnregister(unsigned long ulBase); +extern void WatchdogIntEnable(unsigned long ulBase); +extern unsigned long WatchdogIntStatus(unsigned long ulBase, tBoolean bMasked); +extern void WatchdogIntClear(unsigned long ulBase); +extern void WatchdogStallDisable(unsigned long ulBase); +extern void WatchdogStallDisable(unsigned long ulBase); + +#ifdef __cplusplus +} +#endif + +#endif // __WATCHDOG_H__ diff --git a/Demo/CORTEX_LM3S811_GCC/init/startup.c b/Demo/CORTEX_LM3S811_GCC/init/startup.c new file mode 100644 index 000000000..407a49792 --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/init/startup.c @@ -0,0 +1,221 @@ +//***************************************************************************** +// +// startup.c - Boot code for Stellaris. +// +// Copyright (c) 2005-2007 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// 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. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 1049 of the Stellaris Driver Library. +// +//***************************************************************************** + +//***************************************************************************** +// +// Forward declaration of the default fault handlers. +// +//***************************************************************************** +void ResetISR(void); +static void NmiSR(void); +static void FaultISR(void); +static void IntDefaultHandler(void); +extern void xPortPendSVHandler(void); +extern void xPortSysTickHandler(void); +extern void vUART_ISR( void ); +extern void vGPIO_ISR( void ); + +//***************************************************************************** +// +// The entry point for the application. +// +//***************************************************************************** +extern int main(void); + +//***************************************************************************** +// +// Reserve space for the system stack. +// +//***************************************************************************** +#ifndef STACK_SIZE +#define STACK_SIZE 64 +#endif +static unsigned long pulStack[STACK_SIZE]; + +//***************************************************************************** +// +// The minimal vector table for a Cortex M3. Note that the proper constructs +// must be placed on this to ensure that it ends up at physical address +// 0x0000.0000. +// +//***************************************************************************** +__attribute__ ((section(".isr_vector"))) +void (* const g_pfnVectors[])(void) = +{ + (void (*)(void))((unsigned long)pulStack + sizeof(pulStack)), + // The initial stack pointer + ResetISR, // The reset handler + NmiSR, // The NMI handler + FaultISR, // The hard fault handler + IntDefaultHandler, // The MPU fault handler + IntDefaultHandler, // The bus fault handler + IntDefaultHandler, // The usage fault handler + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + IntDefaultHandler, // SVCall handler + IntDefaultHandler, // Debug monitor handler + 0, // Reserved + xPortPendSVHandler, // The PendSV handler + xPortSysTickHandler, // The SysTick handler + IntDefaultHandler, // GPIO Port A + IntDefaultHandler, // GPIO Port B + vGPIO_ISR, // GPIO Port C + IntDefaultHandler, // GPIO Port D + IntDefaultHandler, // GPIO Port E + vUART_ISR, // UART0 Rx and Tx + IntDefaultHandler, // UART1 Rx and Tx + IntDefaultHandler, // SSI Rx and Tx + IntDefaultHandler, // I2C Master and Slave + IntDefaultHandler, // PWM Fault + IntDefaultHandler, // PWM Generator 0 + IntDefaultHandler, // PWM Generator 1 + IntDefaultHandler, // PWM Generator 2 + IntDefaultHandler, // Quadrature Encoder + IntDefaultHandler, // ADC Sequence 0 + IntDefaultHandler, // ADC Sequence 1 + IntDefaultHandler, // ADC Sequence 2 + IntDefaultHandler, // ADC Sequence 3 + IntDefaultHandler, // Watchdog timer + IntDefaultHandler, // Timer 0 subtimer A + IntDefaultHandler, // Timer 0 subtimer B + IntDefaultHandler, // Timer 1 subtimer A + IntDefaultHandler, // Timer 1 subtimer B + IntDefaultHandler, // Timer 2 subtimer A + IntDefaultHandler, // Timer 2 subtimer B + IntDefaultHandler, // Analog Comparator 0 + IntDefaultHandler, // Analog Comparator 1 + IntDefaultHandler, // Analog Comparator 2 + IntDefaultHandler, // System Control (PLL, OSC, BO) + IntDefaultHandler // FLASH Control +}; + +//***************************************************************************** +// +// The following are constructs created by the linker, indicating where the +// the "data" and "bss" segments reside in memory. The initializers for the +// for the "data" segment resides immediately following the "text" segment. +// +//***************************************************************************** +extern unsigned long _etext; +extern unsigned long _data; +extern unsigned long _edata; +extern unsigned long _bss; +extern unsigned long _ebss; + +//***************************************************************************** +// +// This is the code that gets called when the processor first starts execution +// following a reset event. Only the absolutely necessary set is performed, +// after which the application supplied main() routine is called. Any fancy +// actions (such as making decisions based on the reset cause register, and +// resetting the bits in that register) are left solely in the hands of the +// application. +// +//***************************************************************************** +void +ResetISR(void) +{ + unsigned long *pulSrc, *pulDest; + + // + // Copy the data segment initializers from flash to SRAM. + // + pulSrc = &_etext; + for(pulDest = &_data; pulDest < &_edata; ) + { + *pulDest++ = *pulSrc++; + } + + // + // Zero fill the bss segment. + // + for(pulDest = &_bss; pulDest < &_ebss; ) + { + *pulDest++ = 0; + } + + // + // Call the application's entry point. + // + main(); +} + +//***************************************************************************** +// +// This is the code that gets called when the processor receives a NMI. This +// simply enters an infinite loop, preserving the system state for examination +// by a debugger. +// +//***************************************************************************** +static void +NmiSR(void) +{ + // + // Enter an infinite loop. + // + while(1) + { + } +} + +//***************************************************************************** +// +// This is the code that gets called when the processor receives a fault +// interrupt. This simply enters an infinite loop, preserving the system state +// for examination by a debugger. +// +//***************************************************************************** +static void +FaultISR(void) +{ + // + // Enter an infinite loop. + // + while(1) + { + } +} + +//***************************************************************************** +// +// This is the code that gets called when the processor receives an unexpected +// interrupt. This simply enters an infinite loop, preserving the system state +// for examination by a debugger. +// +//***************************************************************************** +static void +IntDefaultHandler(void) +{ + // + // Go into an infinite loop. + // + while(1) + { + } +} diff --git a/Demo/CORTEX_LM3S811_GCC/main.c b/Demo/CORTEX_LM3S811_GCC/main.c new file mode 100644 index 000000000..44b65eaaf --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/main.c @@ -0,0 +1,362 @@ +/* + FreeRTOS.org V4.1.3 - Copyright (C) 2003-2006 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + FreeRTOS.org 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 + along with FreeRTOS.org; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + A special exception to the GPL can be applied should you wish to distribute + a combined work that includes FreeRTOS.org, without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details of how and when the exception + can be applied. + + *************************************************************************** + See http://www.FreeRTOS.org for documentation, latest information, license + and contact details. Please ensure to read the configuration and relevant + port sections of the online documentation. + *************************************************************************** +*/ + + +/* + * This project contains an application demonstrating the use of the + * FreeRTOS.org mini real time scheduler on the Luminary Micro LM3S811 Eval + * board. See http://www.FreeRTOS.org for more information. + * + * main() simply sets up the hardware, creates all the demo application tasks, + * then starts the scheduler. http://www.freertos.org/a00102.html provides + * more information on the standard demo tasks. + * + * In addition to a subset of the standard demo application tasks, main.c also + * defines the following tasks: + * + * + A 'Print' task. The print task is the only task permitted to access the + * LCD - thus ensuring mutual exclusion and consistent access to the resource. + * Other tasks do not access the LCD directly, but instead send the text they + * wish to display to the print task. The print task spends most of its time + * blocked - only waking when a message is queued for display. + * + * + A 'Button handler' task. The eval board contains a user push button that + * is configured to generate interrupts. The interrupt handler uses a + * semaphore to wake the button handler task - demonstrating how the priority + * mechanism can be used to defer interrupt processing to the task level. The + * button handler task sends a message both to the LCD (via the print task) and + * the UART where it can be viewed using a dumb terminal (via the UART to USB + * converter on the eval board). NOTES: The dumb terminal must be closed in + * order to reflash the microcontroller. A very basic interrupt driven UART + * driver is used that does not use the FIFO. 19200 baud is used. + * + * + A 'check' task. The check task only executes every five seconds but has a + * high priority so is guaranteed to get processor time. Its function is to + * check that all the other tasks are still operational and that no errors have + * been detected at any time. If no errors have every been detected 'PASS' is + * written to the display (via the print task) - if an error has ever been + * detected the message is changed to 'FAIL'. The position of the message is + * changed for each write. + */ + + + +/* Environment includes. */ +#include "DriverLib.h" + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" + +/* Demo app includes. */ +#include "integer.h" +#include "PollQ.h" +#include "semtest.h" +#include "BlockQ.h" + +/* Delay between cycles of the 'check' task. */ +#define mainCHECK_DELAY ( ( portTickType ) 5000 / portTICK_RATE_MS ) + +/* UART configuration - note this does not use the FIFO so is not very +efficient. */ +#define mainBAUD_RATE ( 19200 ) +#define mainFIFO_SET ( 0x10 ) + +/* Demo task priorities. */ +#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) +#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) +#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 ) + +/* Demo board specifics. */ +#define mainPUSH_BUTTON GPIO_PIN_4 + +/* Misc. */ +#define mainQUEUE_SIZE ( 3 ) +#define mainDEBOUNCE_DELAY ( ( portTickType ) 150 / portTICK_RATE_MS ) +#define mainNO_DELAY ( ( portTickType ) 0 ) +/* + * Configure the processor and peripherals for this demo. + */ +static void prvSetupHardware( void ); + +/* + * The 'check' task, as described at the top of this file. + */ +static void vCheckTask( void *pvParameters ); + +/* + * The task that is woken by the ISR that processes GPIO interrupts originating + * from the push button. + */ +static void vButtonHandlerTask( void *pvParameters ); + +/* + * The task that controls access to the LCD. + */ +static void vPrintTask( void *pvParameter ); + +/* String that is transmitted on the UART. */ +static portCHAR *cMessage = "Task woken by button interrupt! --- "; +static volatile portCHAR *pcNextChar; + +/* The semaphore used to wake the button handler task from within the GPIO +interrupt handler. */ +xSemaphoreHandle xButtonSemaphore; + +/* The queue used to send strings to the print task for display on the LCD. */ +xQueueHandle xPrintQueue; + +/*-----------------------------------------------------------*/ + +int main( void ) +{ + /* Configure the clocks, UART and GPIO. */ + prvSetupHardware(); + + /* Create the semaphore used to wake the button handler task from the GPIO + ISR. */ + vSemaphoreCreateBinary( xButtonSemaphore ); + xSemaphoreTake( xButtonSemaphore, 0 ); + + /* Create the queue used to pass message to vPrintTask. */ + xPrintQueue = xQueueCreate( mainQUEUE_SIZE, sizeof( portCHAR * ) ); + + /* Start the standard demo tasks. */ + vStartIntegerMathTasks( tskIDLE_PRIORITY ); + vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); + vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); + vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); + + /* Start the tasks defined within the file. */ + xTaskCreate( vCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); + xTaskCreate( vButtonHandlerTask, "Status", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY + 1, NULL ); + xTaskCreate( vPrintTask, "Print", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY - 1, NULL ); + + /* Start the scheduler. */ + vTaskStartScheduler(); + + /* Will only get here if there was insufficient heap to start the + scheduler. */ + + return 0; +} +/*-----------------------------------------------------------*/ + +static void vCheckTask( void *pvParameters ) +{ +portBASE_TYPE xErrorOccurred = pdFALSE; +portTickType xLastExecutionTime; +const portCHAR *pcPassMessage = "PASS"; +const portCHAR *pcFailMessage = "FAIL"; + + /* Initialise xLastExecutionTime so the first call to vTaskDelayUntil() + works correctly. */ + xLastExecutionTime = xTaskGetTickCount(); + + for( ;; ) + { + /* Perform this check every mainCHECK_DELAY milliseconds. */ + vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY ); + + /* Has an error been found in any task? */ + + if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) + { + xErrorOccurred = pdTRUE; + } + + if( xArePollingQueuesStillRunning() != pdTRUE ) + { + xErrorOccurred = pdTRUE; + } + + if( xAreSemaphoreTasksStillRunning() != pdTRUE ) + { + xErrorOccurred = pdTRUE; + } + + if( xAreBlockingQueuesStillRunning() != pdTRUE ) + { + xErrorOccurred = pdTRUE; + } + + /* Send either a pass or fail message. If an error is found it is + never cleared again. We do not write directly to the LCD, but instead + queue a message for display by the print task. */ + if( xErrorOccurred == pdTRUE ) + { + xQueueSend( xPrintQueue, &pcFailMessage, portMAX_DELAY ); + } + else + { + xQueueSend( xPrintQueue, &pcPassMessage, portMAX_DELAY ); + } + } +} +/*-----------------------------------------------------------*/ + +static void prvSetupHardware( void ) +{ + /* Setup the PLL. */ + SysCtlClockSet( SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_6MHZ ); + + /* Setup the push button. */ + SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC); + GPIODirModeSet(GPIO_PORTC_BASE, mainPUSH_BUTTON, GPIO_DIR_MODE_IN); + GPIOIntTypeSet( GPIO_PORTC_BASE, mainPUSH_BUTTON,GPIO_FALLING_EDGE ); + GPIOPinIntEnable( GPIO_PORTC_BASE, mainPUSH_BUTTON ); + IntEnable( INT_GPIOC ); + + + + /* Enable the UART. */ + SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); + SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); + + /* Set GPIO A0 and A1 as peripheral function. They are used to output the + UART signals. */ + GPIODirModeSet( GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_DIR_MODE_HW ); + + /* Configure the UART for 8-N-1 operation. */ + UARTConfigSet( UART0_BASE, mainBAUD_RATE, UART_CONFIG_WLEN_8 | UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE ); + + /* We don't want to use the fifo. This is for test purposes to generate + as many interrupts as possible. */ + HWREG( UART0_BASE + UART_O_LCR_H ) &= ~mainFIFO_SET; + + /* Enable Tx interrupts. */ + HWREG( UART0_BASE + UART_O_IM ) |= UART_INT_TX; + IntEnable( INT_UART0 ); + + + /* Initialise the LCD> */ + OSRAMInit( false ); + OSRAMStringDraw("www.FreeRTOS.org", 0, 0); + OSRAMStringDraw("LM3S811 demo", 16, 1); +} +/*-----------------------------------------------------------*/ + +static void vButtonHandlerTask( void *pvParameters ) +{ +const portCHAR *pcInterruptMessage = "Int"; + + for( ;; ) + { + /* Wait for a GPIO interrupt to wake this task. */ + while( xSemaphoreTake( xButtonSemaphore, portMAX_DELAY ) != pdPASS ); + + /* Start the Tx of the message on the UART. */ + UARTIntDisable( UART0_BASE, UART_INT_TX ); + { + pcNextChar = cMessage; + + /* Send the first character. */ + if( !( HWREG( UART0_BASE + UART_O_FR ) & UART_FR_TXFF ) ) + { + HWREG( UART0_BASE + UART_O_DR ) = *pcNextChar; + } + + pcNextChar++; + } + UARTIntEnable(UART0_BASE, UART_INT_TX); + + /* Queue a message for the print task to display on the LCD. */ + xQueueSend( xPrintQueue, &pcInterruptMessage, portMAX_DELAY ); + + /* Make sure we don't process bounces. */ + vTaskDelay( mainDEBOUNCE_DELAY ); + xSemaphoreTake( xButtonSemaphore, mainNO_DELAY ); + } +} + +/*-----------------------------------------------------------*/ + +void vUART_ISR(void) +{ +unsigned portLONG ulStatus; + + /* What caused the interrupt. */ + ulStatus = UARTIntStatus( UART0_BASE, pdTRUE ); + + /* Clear the interrupt. */ + UARTIntClear( UART0_BASE, ulStatus ); + + /* Was a Tx interrupt pending? */ + if( ulStatus & UART_INT_TX ) + { + /* Send the next character in the string. We are not using the FIFO. */ + if( *pcNextChar != 0 ) + { + if( !( HWREG( UART0_BASE + UART_O_FR ) & UART_FR_TXFF ) ) + { + HWREG( UART0_BASE + UART_O_DR ) = *pcNextChar; + } + pcNextChar++; + } + } +} +/*-----------------------------------------------------------*/ + +void vGPIO_ISR( void ) +{ + /* Clear the interrupt. */ + GPIOPinIntClear(GPIO_PORTC_BASE, mainPUSH_BUTTON); + + /* Wake the button handler task. */ + if( xSemaphoreGiveFromISR( xButtonSemaphore, pdFALSE ) ) + { + portEND_SWITCHING_ISR( pdTRUE ); + } +} +/*-----------------------------------------------------------*/ + +static void vPrintTask( void *pvParameters ) +{ +portCHAR *pcMessage; +unsigned portBASE_TYPE uxLine = 0, uxRow = 0; + + for( ;; ) + { + /* Wait for a message to arrive. */ + xQueueReceive( xPrintQueue, &pcMessage, portMAX_DELAY ); + + /* Write the message to the LCD. */ + uxRow++; + uxLine++; + OSRAMClear(); + OSRAMStringDraw( pcMessage, uxLine & 0x3f, uxRow & 0x01); + } +} + diff --git a/Demo/CORTEX_LM3S811_GCC/makedefs b/Demo/CORTEX_LM3S811_GCC/makedefs new file mode 100644 index 000000000..efd7530d4 --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/makedefs @@ -0,0 +1,208 @@ +#****************************************************************************** +# +# makedefs - Definitions common to all makefiles. +# +# Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved. +# +# Software License Agreement +# +# Luminary Micro, Inc. (LMI) is supplying this software for use solely and +# exclusively on LMI's Stellaris Family of microcontroller products. +# +# The software is owned by LMI and/or its suppliers, and is protected under +# applicable copyright laws. All rights are reserved. Any use in violation +# of the foregoing restrictions may subject the user to criminal sanctions +# under applicable laws, as well as to civil liability for the breach of the +# terms and conditions of this license. +# +# 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. +# LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +# CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +# +#****************************************************************************** + +#****************************************************************************** +# +# Get the operating system name. If this is Cygwin, the .d files will be +# munged to convert c: into /cygdrive/c so that "make" will be happy with the +# auto-generated dependencies. +# +#****************************************************************************** +os:=${shell uname -s} + +#****************************************************************************** +# +# The compiler to be used. +# +#****************************************************************************** +ifndef COMPILER +COMPILER=gcc +endif + +#****************************************************************************** +# +# The debugger to be used. +# +#****************************************************************************** +ifndef DEBUGGER +DEBUGGER=gdb +endif + +#****************************************************************************** +# +# Definitions for using GCC. +# +#****************************************************************************** +ifeq (${COMPILER}, gcc) + +# +# The command for calling the compiler. +# +CC=arm-stellaris-eabi-gcc + +# +# The flags passed to the assembler. +# +AFLAGS=-mthumb \ + -mcpu=cortex-m3 \ + -MD + +# +# The flags passed to the compiler. +# +CFLAGS=-mthumb \ + -mcpu=cortex-m3 \ + -O2 \ + -MD + +# +# The command for calling the library archiver. +# +AR=arm-stellaris-eabi-ar + +# +# The command for calling the linker. +# +LD=arm-stellaris-eabi-ld + +# +# The flags passed to the linker. +# +LDFLAGS= -Map gcc/out.map + +# +# Get the location of libgcc.a from the GCC front-end. +# +LIBGCC=${shell ${CC} -mthumb -march=armv6t2 -print-libgcc-file-name} + +# +# Get the location of libc.a from the GCC front-end. +# +LIBC=${shell ${CC} -mthumb -march=armv6t2 -print-file-name=libc.a} + +# +# The command for extracting images from the linked executables. +# +OBJCOPY=arm-stellaris-eabi-objcopy + +endif + +#****************************************************************************** +# +# Tell the compiler to include debugging information if the DEBUG environment +# variable is set. +# +#****************************************************************************** +ifdef DEBUG +CFLAGS += -g +endif + +#****************************************************************************** +# +# The rule for building the object file from each C source file. +# +#****************************************************************************** +${COMPILER}/%.o: %.c + @if [ 'x${VERBOSE}' = x ]; \ + then \ + echo " CC ${<}"; \ + else \ + echo ${CC} ${CFLAGS} -D${COMPILER} -o ${@} -c ${<}; \ + fi + @${CC} ${CFLAGS} -D${COMPILER} -o ${@} -c ${<} +ifeq (${COMPILER}, rvds) + @mv -f ${notdir ${@:.o=.d}} ${COMPILER} +endif +ifneq ($(findstring CYGWIN, ${os}), ) + @perl -i.bak -p -e 's/[Cc]:/\/cygdrive\/c/g' ${@:.o=.d} +endif + +#****************************************************************************** +# +# The rule for building the object file from each assembly source file. +# +#****************************************************************************** +${COMPILER}/%.o: %.S + @if [ 'x${VERBOSE}' = x ]; \ + then \ + echo " CC ${<}"; \ + else \ + echo ${CC} ${AFLAGS} -D${COMPILER} -o ${@} -c ${<}; \ + fi +ifeq (${COMPILER}, rvds) + @${CC} ${AFLAGS} -D${COMPILER} -E ${<} > ${@:.o=_.S} + @${CC} ${AFLAGS} -o ${@} -c ${@:.o=_.S} + @rm ${@:.o=_.S} + @${CC} ${AFLAGS} -D${COMPILER} --md -E ${<} + @sed 's,,${@},g' ${notdir ${<:.S=.d}} > ${@:.o=.d} + @rm ${notdir ${<:.S=.d}} +endif +ifeq (${COMPILER}, gcc) + @${CC} ${AFLAGS} -D${COMPILER} -o ${@} -c ${<} +endif +ifneq ($(findstring CYGWIN, ${os}), ) + @perl -i.bak -p -e 's/[Cc]:/\/cygdrive\/c/g' ${@:.o=.d} +endif + +#****************************************************************************** +# +# The rule for creating an object library. +# +#****************************************************************************** +${COMPILER}/%.a: + @if [ 'x${VERBOSE}' = x ]; \ + then \ + echo " AR ${@}"; \ + else \ + echo ${AR} -cr ${@} ${^}; \ + fi + @${AR} -cr ${@} ${^} + +#****************************************************************************** +# +# The rule for linking the application. +# +#****************************************************************************** +${COMPILER}/%.axf: + @if [ 'x${VERBOSE}' = x ]; \ + then \ + echo " LD ${@}"; \ + fi +ifeq (${COMPILER}, gcc) + @if [ 'x${VERBOSE}' != x ]; \ + then \ + echo ${LD} -T ${SCATTER_${notdir ${@:.axf=}}} \ + --entry ${ENTRY_${notdir ${@:.axf=}}} \ + ${LDFLAGSgcc_${notdir ${@:.axf=}}} \ + ${LDFLAGS} -o ${@} ${^} \ + '${LIBC}' '${LIBGCC}'; \ + fi + @${LD} -T ${SCATTER_${notdir ${@:.axf=}}} \ + --entry ${ENTRY_${notdir ${@:.axf=}}} \ + ${LDFLAGSgcc_${notdir ${@:.axf=}}} \ + ${LDFLAGS} -o ${@} ${^} \ + '${LIBC}' '${LIBGCC}' + @${OBJCOPY} -O binary ${@} ${@:.axf=.bin} +endif diff --git a/Demo/CORTEX_LM3S811_GCC/standalone.ld b/Demo/CORTEX_LM3S811_GCC/standalone.ld new file mode 100644 index 000000000..8ee3fe2f8 --- /dev/null +++ b/Demo/CORTEX_LM3S811_GCC/standalone.ld @@ -0,0 +1,60 @@ +/****************************************************************************** + * + * standalone.ld - Linker script for applications using startup.c and + * DriverLib. + * + * Copyright (c) 2005-2007 Luminary Micro, Inc. All rights reserved. + * + * Software License Agreement + * + * Luminary Micro, Inc. (LMI) is supplying this software for use solely and + * exclusively on LMI's microcontroller products. + * + * The software is owned by LMI and/or its suppliers, and is protected under + * applicable copyright laws. All rights are reserved. Any use in violation + * of the foregoing restrictions may subject the user to criminal sanctions + * under applicable laws, as well as to civil liability for the breach of the + * terms and conditions of this license. + * + * 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. + * LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + * + * This is part of revision 1049 of the Stellaris Driver Library. + * + *****************************************************************************/ + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 64K + SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 8K +} + +SECTIONS +{ + .text : + { + KEEP(*(.isr_vector)) + *(.text) + *(.rodata*) + _etext = .; + } > FLASH + + .data : AT (ADDR(.text) + SIZEOF(.text)) + { + _data = .; + *(vtable) + *(.data) + _edata = .; + } > SRAM + + .bss : + { + _bss = .; + *(.bss) + *(COMMON) + _ebss = .; + } > SRAM +} -- 2.39.5