summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2015-03-23 09:12:52 -0600
committerGregory Nutt <gnutt@nuttx.org>2015-03-23 09:12:52 -0600
commit7ae05b1a24503aea81a01305f9488c2d7be2946a (patch)
treecd53e4254c42564ba29d2d1842ee802d1d579eb1
parent510496d8fbcf3dc46263f1971bc0756d75b1479e (diff)
downloadpx4-nuttx-7ae05b1a24503aea81a01305f9488c2d7be2946a.tar.gz
px4-nuttx-7ae05b1a24503aea81a01305f9488c2d7be2946a.tar.bz2
px4-nuttx-7ae05b1a24503aea81a01305f9488c2d7be2946a.zip
- ADC driver has been re-organized; configuration is now handled in code
instead of Kconfig to help reduce bloat and confusion. - Timer changed to remove ADC coupling in Kconfig to code and moved configuration up from arch/arm/src/tiva to configs/tm4c123g-launchpad/src. - GPIO driver needed small fixes in the configuration routines and discovered false-positive bugs in interrupt testing: interrupts are now verified to actually be working reliably. - Attempt to apply some consistency in the tiva arch/ level's interface to the config/board/ level driver configuration. From Calvin Maguranis
-rw-r--r--nuttx/arch/arm/src/tiva/Kconfig900
-rw-r--r--nuttx/arch/arm/src/tiva/Make.defs3
-rw-r--r--nuttx/arch/arm/src/tiva/chip/tiva_adc.h283
-rw-r--r--nuttx/arch/arm/src/tiva/tiva_adc.c2820
-rw-r--r--nuttx/arch/arm/src/tiva/tiva_adc.h594
-rw-r--r--nuttx/arch/arm/src/tiva/tiva_adclib.c1104
-rw-r--r--nuttx/arch/arm/src/tiva/tiva_adclow.c1030
-rw-r--r--nuttx/arch/arm/src/tiva/tiva_gpio.c646
-rw-r--r--nuttx/arch/arm/src/tiva/tiva_gpio.h231
-rw-r--r--nuttx/arch/arm/src/tiva/tiva_gpioirq.c573
-rw-r--r--nuttx/arch/arm/src/tiva/tiva_timer.h10
-rw-r--r--nuttx/arch/arm/src/tiva/tiva_timerlib.c8
-rw-r--r--nuttx/arch/arm/src/tiva/tiva_timerlow32.c34
13 files changed, 3838 insertions, 4398 deletions
diff --git a/nuttx/arch/arm/src/tiva/Kconfig b/nuttx/arch/arm/src/tiva/Kconfig
index 2691373c4..43b07f944 100644
--- a/nuttx/arch/arm/src/tiva/Kconfig
+++ b/nuttx/arch/arm/src/tiva/Kconfig
@@ -790,7 +790,7 @@ endif # TIVA_I2C
if TIVA_TIMER
-menu "Tiva Timer Configuration"
+menu "Timer Configuration"
config TIVA_TIMER_32BIT
bool "32-bit timer support"
@@ -802,14 +802,6 @@ config TIVA_TIMER32_PERIODIC
bool "32-bit one-shot/periodic timer support"
default n
-config TIVA_TIMER32_ADCEVENT
- bool "32-bit one-shot/periodic timer ADC event support"
- default n
- depends on TIVA_TIMER32_PERIODIC
- depends on TIVA_TIMER_32BIT
- ---help---
- Enable timer support for triggering an ADC sample on timeout.
-
config TIVA_TIMER32_RTC
bool "32-bit RTC (needs 32.768-KHz input)"
default n
@@ -817,7 +809,7 @@ config TIVA_TIMER32_RTC
endif # TIVA_TIMER_32BIT
config TIVA_TIMER_16BIT
- bool "16-bit Timers"
+ bool "16-bit timer support"
default n
if TIVA_TIMER_16BIT
@@ -826,14 +818,6 @@ config TIVA_TIMER16_PERIODIC
bool "16-bit one-shot/periodic timer support"
default n
-config TIVA_TIMER16_ADCEVENT
- bool "16-bit one-shot/periodic timer ADC event support"
- default n
- depends on TIVA_TIMER16_PERIODIC
- depends on TIVA_TIMER_16BIT
- ---help---
- Enable timer support for triggering an ADC sample on timeout.
-
config TIVA_TIMER16_EDGECOUNT
bool "16-bit input edge-count capture support"
default n
@@ -862,883 +846,7 @@ endmenu # Tiva Timer Configuration
endif # TIVA_TIMER
if TIVA_ADC
-menu "Tiva ADC Configuration"
-
-config TIVA_ADC_CLOCK
- int "ADC clock in MHz"
- default 16000000
- range 16000000 32000000
- depends on ARM_CHIP_TM4C129
- ---help---
- Clocking can only be configured for the TM4C129; The TM4C129 ADC can be clocked from
- 16 MHz to 32 MHz. The TM4C123 clock is limited to 16 MHz.
-
-if TIVA_ADC0
-
-menuconfig TIVA_ADC0_SSE0
- bool "Enable and configure ADC0 SSE0"
- default n
- ---help---
- Select this Sample Sequencer for operation. There are 0-3,4-7 possible SSEs
- depending on how many ADC peripherals are available (4 per each ADC).
-
- Configuration variables:
- - trigger select
- - priority
- - input channel step assignment
-
-config TIVA_ADC0_SSE0_PRIORITY
- int "Conversion priority, must be a value from 0 to 3, no duplicates"
- default 0
- range 0 3
- depends on TIVA_ADC0_SSE0
- ---help---
- Set the conversion priority for this SSE. Each ADC has 4 SSEs so the
- order in which they are serviced is determined by this value.
-
-config TIVA_ADC0_SSE0_TRIGGER
- int "Set the trigger source to start a SSE's conversion, see help for options"
- default 0
- range 0 15
- depends on TIVA_ADC0_SSE0
- ---help---
- Set the trigger source. The following values correspond to the
- following triggers:
- - 0x0: Processor (default)
- - 0x1: *Analog Comparator 0
- - 0x2: *Analog Comparator 1
- - 0x3: *Analog Comparator 2
- - 0x4: External (GPIO Pins)
- - 0x5: Timer
- - 0x6: **PWM generator 0
- - 0x7: **PWM generator 1
- - 0x8: **PWM generator 2
- - 0x9: **PWM generator 3
- - 0xE: Never Trigger
- - 0xF: Always (continuously sample)
-
- * Comparators are unsupported
- ** PWM triggering requires additional setup at runtime - There is a special
- ADC IOCTL defined in the Tiva ADC driver for this purpose.
-
-menuconfig TIVA_ADC0_SSE0_STEP0
- bool "Enable and configure ADC0 SSE0 step 0"
- default n
- depends on TIVA_ADC0_SSE0
-
-config TIVA_ADC0_SSE0_STEP0_TS
- bool "This step will retrieve data from the on-chip temperature sensor."
- default n
- depends on TIVA_ADC0_SSE0_STEP0
-
-config TIVA_ADC0_SSE0_STEP0_AIN
- int "Set the input AIN. See datasheet for pin to AIN mappings."
- default 0
- depends on TIVA_ADC0_SSE0_STEP0
-
-menuconfig TIVA_ADC0_SSE0_STEP1
- bool "Enable and configure ADC0 SSE0 step 1"
- default n
- depends on TIVA_ADC0_SSE0
-
-config TIVA_ADC0_SSE0_STEP1_TS
- bool "This step will retrieve data from the on-chip temperature sensor."
- default n
- depends on TIVA_ADC0_SSE0_STEP1
-
-config TIVA_ADC0_SSE0_STEP1_AIN
- int "Set the input AIN. See datasheet for pin to AIN mappings."
- default 0
- depends on TIVA_ADC0_SSE0_STEP1
-
-menuconfig TIVA_ADC0_SSE0_STEP2
- bool "Enable and configure ADC0 SSE0 step 2"
- default n
- depends on TIVA_ADC0_SSE0
-
-config TIVA_ADC0_SSE0_STEP2_TS
- bool "This step will retrieve data from the on-chip temperature sensor."
- default n
- depends on TIVA_ADC0_SSE0_STEP2
-
-config TIVA_ADC0_SSE0_STEP2_AIN
- int "Set the input AIN. See datasheet for pin to AIN mappings."
- default 0
- depends on TIVA_ADC0_SSE0_STEP2
-
-menuconfig TIVA_ADC0_SSE0_STEP3
- bool "Enable and configure ADC0 SSE0 step 3"
- default n
- depends on TIVA_ADC0_SSE0
-
-config TIVA_ADC0_SSE0_STEP3_TS
- bool "This step will retrieve data from the on-chip temperature sensor."
- default n
- depends on TIVA_ADC0_SSE0_STEP3
-
-config TIVA_ADC0_SSE0_STEP3_AIN
- int "Set the input AIN. See datasheet for pin to AIN mappings."
- default 0
- depends on TIVA_ADC0_SSE0_STEP3
-
-menuconfig TIVA_ADC0_SSE0_STEP4
- bool "Enable and configure ADC0 SSE0 step 4"
- default n
- depends on TIVA_ADC0_SSE0
-
-config TIVA_ADC0_SSE0_STEP4_TS
- bool "This step will retrieve data from the on-chip temperature sensor."
- default n
- depends on TIVA_ADC0_SSE0_STEP4
-
-config TIVA_ADC0_SSE0_STEP4_AIN
- int "Set the input AIN. See datasheet for pin to AIN mappings."
- default 0
- depends on TIVA_ADC0_SSE0_STEP4
-
-menuconfig TIVA_ADC0_SSE0_STEP5
- bool "Enable and configure ADC0 SSE0 step 5"
- default n
- depends on TIVA_ADC0_SSE0
-
-config TIVA_ADC0_SSE0_STEP5_TS
- bool "This step will retrieve data from the on-chip temperature sensor."
- default n
- depends on TIVA_ADC0_SSE0_STEP5
-
-config TIVA_ADC0_SSE0_STEP5_AIN
- int "Set the input AIN. See datasheet for pin to AIN mappings."
- default 0
- depends on TIVA_ADC0_SSE0_STEP5
-
-menuconfig TIVA_ADC0_SSE0_STEP6
- bool "Enable and configure ADC0 SSE0 step 6"
- default n
- depends on TIVA_ADC0_SSE0
-
-config TIVA_ADC0_SSE0_STEP6_TS
- bool "This step will retrieve data from the on-chip temperature sensor."
- default n
- depends on TIVA_ADC0_SSE0_STEP6
-
-config TIVA_ADC0_SSE0_STEP6_AIN
- int "Set the input AIN. See datasheet for pin to AIN mappings."
- default 0
- depends on TIVA_ADC0_SSE0_STEP6
-
-menuconfig TIVA_ADC0_SSE0_STEP7
- bool "Enable and configure ADC0 SSE0 step 7"
- default n
- depends on TIVA_ADC0_SSE0
-
-config TIVA_ADC0_SSE0_STEP7_TS
- bool "This step will retrieve data from the on-chip temperature sensor."
- default n
- depends on TIVA_ADC0_SSE0_STEP7
-
-config TIVA_ADC0_SSE0_STEP7_AIN
- int "Set the input AIN. See datasheet for pin to AIN mappings."
- default 0
- depends on TIVA_ADC0_SSE0_STEP7
-
-menuconfig TIVA_ADC0_SSE1
- bool "Enable and configure ADC0 SSE1"
- default n
- ---help---
- Select this Sample Sequencer for operation. There are 0-3,4-7 possible SSEs
- depending on how many ADC peripherals are available (4 per each ADC).
-
- Configuration variables:
- - trigger select
- - priority
- - input channel step assignment
-
-config TIVA_ADC0_SSE1_PRIORITY
- int "Conversion priority, must be a value from 0 to 3, no duplicates"
- default 0
- depends on TIVA_ADC0_SSE1
- ---help---
- Set the conversion priority for this SSE. Each ADC has 4 SSEs so the
- order in which they are serviced is determined by this value.
-config TIVA_ADC0_SSE1_TRIGGER
- int "Set the trigger source to start a SSE's conversion, see help for options"
- default 0
- depends on TIVA_ADC0_SSE1
- ---help---
- Set the trigger source. The following values correspond to the
- following triggers:
- - 0x0: Processor (default)
- - 0x1: *Analog Comparator 0
- - 0x2: *Analog Comparator 1
- - 0x3: *Analog Comparator 2
- - 0x4: External (GPIO Pins)
- - 0x5: Timer
- - 0x6: **PWM generator 0
- - 0x7: **PWM generator 1
- - 0x8: **PWM generator 2
- - 0x9: **PWM generator 3
- - 0xE: Never Trigger
- - 0xF: Always (continuously sample)
-
- * Comparators are unsupported
- ** PWM triggering requires additional setup at runtime - There is a special
- ADC IOCTL defined in the Tiva ADC driver for this purpose.
-
-menuconfig TIVA_ADC0_SSE1_STEP0
- bool "Enable and configure ADC0 SSE1 step 0"
- default n
- depends on TIVA_ADC0_SSE1
-
-config TIVA_ADC0_SSE1_STEP0_TS
- bool "This step will retrieve data from the on-chip temperature sensor."
- default n
- depends on TIVA_ADC0_SSE1_STEP0
-
-config TIVA_ADC0_SSE1_STEP0_AIN
- int "Set the input AIN. See datasheet for pin to AIN mappings."
- default 0
- depends on TIVA_ADC0_SSE1_STEP0
-
-menuconfig TIVA_ADC0_SSE1_STEP1
- bool "Enable and configure ADC0 SSE1 step 1"
- default n
- depends on TIVA_ADC0_SSE1
-
-config TIVA_ADC0_SSE1_STEP1_TS
- bool "This step will retrieve data from the on-chip temperature sensor."
- default n
- depends on TIVA_ADC0_SSE1_STEP1
-
-config TIVA_ADC0_SSE1_STEP1_AIN
- int "Set the input AIN. See datasheet for pin to AIN mappings."
- default 0
- depends on TIVA_ADC0_SSE1_STEP1
-
-menuconfig TIVA_ADC0_SSE1_STEP2
- bool "Enable and configure ADC0 SSE1 step 2"
- default n
- depends on TIVA_ADC0_SSE1
-
-config TIVA_ADC0_SSE1_STEP2_TS
- bool "This step will retrieve data from the on-chip temperature sensor."
- default n
- depends on TIVA_ADC0_SSE1_STEP2
-
-config TIVA_ADC0_SSE1_STEP2_AIN
- int "Set the input AIN. See datasheet for pin to AIN mappings."
- default 0
- depends on TIVA_ADC0_SSE1_STEP2
-
-menuconfig TIVA_ADC0_SSE1_STEP3
- bool "Enable and configure ADC0 SSE1 step 3"
- default n
- depends on TIVA_ADC0_SSE1
-
-config TIVA_ADC0_SSE1_STEP3_TS
- bool "This step will retrieve data from the on-chip temperature sensor."
- default n
- depends on TIVA_ADC0_SSE1_STEP3
-
-config TIVA_ADC0_SSE1_STEP3_AIN
- int "Set the input AIN. See datasheet for pin to AIN mappings."
- default 0
- depends on TIVA_ADC0_SSE1_STEP3
-
-menuconfig TIVA_ADC0_SSE2
- bool "Enable and configure ADC0 SSE2"
- default n
- ---help---
- Select this Sample Sequencer for operation. There are 0-3,4-7 possible SSEs
- depending on how many ADC peripherals are available (4 per each ADC).
-
- Configuration variables:
- - trigger select
- - priority
- - input channel step assignment
-
-config TIVA_ADC0_SSE2_PRIORITY
- int "Conversion priority, must be a value from 0 to 3, no duplicates"
- default 0
- depends on TIVA_ADC0_SSE2
- ---help---
- Set the conversion priority for this SSE. Each ADC has 4 SSEs so the
- order in which they are serviced is determined by this value.
-config TIVA_ADC0_SSE2_TRIGGER
- int "Set the trigger source to start a SSE's conversion, see help for options"
- default 0
- depends on TIVA_ADC0_SSE2
- ---help---
- Set the trigger source. The following values correspond to the
- following triggers:
- - 0x0: Processor (default)
- - 0x1: *Analog Comparator 0
- - 0x2: *Analog Comparator 1
- - 0x3: *Analog Comparator 2
- - 0x4: External (GPIO Pins)
- - 0x5: Timer
- - 0x6: **PWM generator 0
- - 0x7: **PWM generator 1
- - 0x8: **PWM generator 2
- - 0x9: **PWM generator 3
- - 0xE: Never Trigger
- - 0xF: Always (continuously sample)
-
- * Comparators are unsupported
- ** PWM triggering requires additional setup at runtime - There is a special
- ADC IOCTL defined in the Tiva ADC driver for this purpose.
-
-menuconfig TIVA_ADC0_SSE2_STEP0
- bool "Enable and configure ADC0 SSE2 step 0"
- default n
- depends on TIVA_ADC0_SSE2
-
-config TIVA_ADC0_SSE2_STEP0_TS
- bool "This step will retrieve data from the on-chip temperature sensor."
- default n
- depends on TIVA_ADC0_SSE2_STEP0
-
-config TIVA_ADC0_SSE2_STEP0_AIN
- int "Set the input AIN. See datasheet for pin to AIN mappings."
- default 0
- depends on TIVA_ADC0_SSE2_STEP0
-
-menuconfig TIVA_ADC0_SSE2_STEP1
- bool "Enable and configure ADC0 SSE2 step 1"
- default n
- depends on TIVA_ADC0_SSE2
-
-config TIVA_ADC0_SSE2_STEP1_TS
- bool "This step will retrieve data from the on-chip temperature sensor."
- default n
- depends on TIVA_ADC0_SSE2_STEP1
-
-config TIVA_ADC0_SSE2_STEP1_AIN
- int "Set the input AIN. See datasheet for pin to AIN mappings."
- default 0
- depends on TIVA_ADC0_SSE2_STEP1
-
-menuconfig TIVA_ADC0_SSE2_STEP2
- bool "Enable and configure ADC0 SSE2 step 2"
- default n
- depends on TIVA_ADC0_SSE2
-
-config TIVA_ADC0_SSE2_STEP2_TS
- bool "This step will retrieve data from the on-chip temperature sensor."
- default n
- depends on TIVA_ADC0_SSE2_STEP2
-
-config TIVA_ADC0_SSE2_STEP2_AIN
- int "Set the input AIN. See datasheet for pin to AIN mappings."
- default 0
- depends on TIVA_ADC0_SSE2_STEP2
-
-menuconfig TIVA_ADC0_SSE2_STEP3
- bool "Enable and configure ADC0 SSE2 step 3"
- default n
- depends on TIVA_ADC0_SSE2
-
-config TIVA_ADC0_SSE2_STEP3_TS
- bool "This step will retrieve data from the on-chip temperature sensor."
- default n
- depends on TIVA_ADC0_SSE2_STEP3
-
-config TIVA_ADC0_SSE2_STEP3_AIN
- int "Set the input AIN. See datasheet for pin to AIN mappings."
- default 0
- depends on TIVA_ADC0_SSE2_STEP3
-
-menuconfig TIVA_ADC0_SSE3
- bool "Enable and configure ADC0 SSE3"
- default n
- ---help---
- Select this Sample Sequencer for operation. There are 0-3,4-7 possible SSEs
- depending on how many ADC peripherals are available (4 per each ADC).
-
- Configuration variables:
- - trigger select
- - priority
- - input channel step assignment
-
-config TIVA_ADC0_SSE3_PRIORITY
- int "Conversion priority, must be a value from 0 to 3, no duplicates"
- default 0
- depends on TIVA_ADC0_SSE3
- ---help---
- Set the conversion priority for this SSE. Each ADC has 4 SSEs so the
- order in which they are serviced is determined by this value.
-config TIVA_ADC0_SSE3_TRIGGER
- int "Set the trigger source to start a SSE's conversion, see help for options"
- default 0
- depends on TIVA_ADC0_SSE3
- ---help---
- Set the trigger source. The following values correspond to the
- following triggers:
- - 0x0: Processor (default)
- - 0x1: *Analog Comparator 0
- - 0x2: *Analog Comparator 1
- - 0x3: *Analog Comparator 2
- - 0x4: External (GPIO Pins)
- - 0x5: Timer
- - 0x6: **PWM generator 0
- - 0x7: **PWM generator 1
- - 0x8: **PWM generator 2
- - 0x9: **PWM generator 3
- - 0xE: Never Trigger
- - 0xF: Always (continuously sample)
-
- * Comparators are unsupported
- ** PWM triggering requires additional setup at runtime - There is a special
- ADC IOCTL defined in the Tiva ADC driver for this purpose.
-
-menuconfig TIVA_ADC0_SSE3_STEP0
- bool "Enable and configure ADC0 SSE3 step 0"
- default n
- depends on TIVA_ADC0_SSE3
-
-config TIVA_ADC0_SSE3_STEP0_TS
- bool "This step will retrieve data from the on-chip temperature sensor."
- default n
- depends on TIVA_ADC0_SSE3_STEP0
-
-config TIVA_ADC0_SSE3_STEP0_AIN
- int "Set the input AIN. See datasheet for pin to AIN mappings."
- default 0
- depends on TIVA_ADC0_SSE3_STEP0
-
-endif # TIVA_ADC0
-
-if TIVA_ADC1
-
-menuconfig TIVA_ADC1_SSE0
- bool "Enable and configure ADC1 SSE0"
- default n
- ---help---
- Select this Sample Sequencer for operation. There are 0-3,4-7 possible SSEs
- depending on how many ADC peripherals are available (4 per each ADC).
-
- Configuration variables:
- - trigger select
- - priority
- - input channel step assignment
-
-config TIVA_ADC1_SSE0_PRIORITY
- int "Conversion priority, must be a value from 0 to 3, no duplicates"
- default 0
- depends on TIVA_ADC1_SSE0
- ---help---
- Set the conversion priority for this SSE. Each ADC has 4 SSEs so the
- order in which they are serviced is determined by this value.
-
-config TIVA_ADC1_SSE0_TRIGGER
- int "Set the trigger source to start a SSE's conversion, see help for options"
- default 0
- depends on TIVA_ADC1_SSE0
- ---help---
- Set the trigger source. The following values correspond to the
- following triggers:
- - 0x0: Processor (default)
- - 0x1: *Analog Comparator 0
- - 0x2: *Analog Comparator 1
- - 0x3: *Analog Comparator 2
- - 0x4: External (GPIO Pins)
- - 0x5: Timer
- - 0x6: **PWM generator 0
- - 0x7: **PWM generator 1
- - 0x8: **PWM generator 2
- - 0x9: **PWM generator 3
- - 0xE: Never Trigger
- - 0xF: Always (continuously sample)
-
- * Comparators are unsupported
- ** PWM triggering requires additional setup at runtime - There is a special
- ADC IOCTL defined in the Tiva ADC driver for this purpose.
-
-menuconfig TIVA_ADC1_SSE0_STEP0
- bool "Enable and configure ADC1 SSE0 step 0"
- default n
- depends on TIVA_ADC1_SSE0
-
-config TIVA_ADC1_SSE0_STEP0_TS
- bool "This step will retrieve data from the on-chip temperature sensor."
- default n
- depends on TIVA_ADC1_SSE0_STEP0
-
-config TIVA_ADC1_SSE0_STEP0_AIN
- int "Set the input AIN. See datasheet for pin to AIN mappings."
- default 0
- depends on TIVA_ADC1_SSE0_STEP0
-
-menuconfig TIVA_ADC1_SSE0_STEP1
- bool "Enable and configure ADC1 SSE0 step 1"
- default n
- depends on TIVA_ADC1_SSE0
-
-config TIVA_ADC1_SSE0_STEP1_TS
- bool "This step will retrieve data from the on-chip temperature sensor."
- default n
- depends on TIVA_ADC1_SSE0_STEP1
-
-config TIVA_ADC1_SSE0_STEP1_AIN
- int "Set the input AIN. See datasheet for pin to AIN mappings."
- default 0
- depends on TIVA_ADC1_SSE0_STEP1
-
-menuconfig TIVA_ADC1_SSE0_STEP2
- bool "Enable and configure ADC1 SSE0 step 2"
- default n
- depends on TIVA_ADC1_SSE0
-
-config TIVA_ADC1_SSE0_STEP2_TS
- bool "This step will retrieve data from the on-chip temperature sensor."
- default n
- depends on TIVA_ADC1_SSE0_STEP2
-
-config TIVA_ADC1_SSE0_STEP2_AIN
- int "Set the input AIN. See datasheet for pin to AIN mappings."
- default 0
- depends on TIVA_ADC1_SSE0_STEP2
-
-menuconfig TIVA_ADC1_SSE0_STEP3
- bool "Enable and configure ADC1 SSE0 step 3"
- default n
- depends on TIVA_ADC1_SSE0
-
-config TIVA_ADC1_SSE0_STEP3_TS
- bool "This step will retrieve data from the on-chip temperature sensor."
- default n
- depends on TIVA_ADC1_SSE0_STEP3
-
-config TIVA_ADC1_SSE0_STEP3_AIN
- int "Set the input AIN. See datasheet for pin to AIN mappings."
- default 0
- depends on TIVA_ADC1_SSE0_STEP3
-
-menuconfig TIVA_ADC1_SSE0_STEP4
- bool "Enable and configure ADC1 SSE0 step 4"
- default n
- depends on TIVA_ADC1_SSE0
-
-config TIVA_ADC1_SSE0_STEP4_TS
- bool "This step will retrieve data from the on-chip temperature sensor."
- default n
- depends on TIVA_ADC1_SSE0_STEP4
-
-config TIVA_ADC1_SSE0_STEP4_AIN
- int "Set the input AIN. See datasheet for pin to AIN mappings."
- default 0
- depends on TIVA_ADC1_SSE0_STEP4
-
-menuconfig TIVA_ADC1_SSE0_STEP5
- bool "Enable and configure ADC1 SSE0 step 5"
- default n
- depends on TIVA_ADC1_SSE0
-
-config TIVA_ADC1_SSE0_STEP5_TS
- bool "This step will retrieve data from the on-chip temperature sensor."
- default n
- depends on TIVA_ADC1_SSE0_STEP5
-
-config TIVA_ADC1_SSE0_STEP5_AIN
- int "Set the input AIN. See datasheet for pin to AIN mappings."
- default 0
- depends on TIVA_ADC1_SSE0_STEP5
-
-menuconfig TIVA_ADC1_SSE0_STEP6
- bool "Enable and configure ADC1 SSE0 step 6"
- default n
- depends on TIVA_ADC1_SSE0
-
-config TIVA_ADC1_SSE0_STEP6_TS
- bool "This step will retrieve data from the on-chip temperature sensor."
- default n
- depends on TIVA_ADC1_SSE0_STEP6
-
-config TIVA_ADC1_SSE0_STEP6_AIN
- int "Set the input AIN. See datasheet for pin to AIN mappings."
- default 0
- depends on TIVA_ADC1_SSE0_STEP6
-
-menuconfig TIVA_ADC1_SSE0_STEP7
- bool "Enable and configure ADC1 SSE0 step 7"
- default n
- depends on TIVA_ADC1_SSE0
-
-config TIVA_ADC1_SSE0_STEP7_TS
- bool "This step will retrieve data from the on-chip temperature sensor."
- default n
- depends on TIVA_ADC1_SSE0_STEP7
-
-config TIVA_ADC1_SSE0_STEP7_AIN
- int "Set the input AIN. See datasheet for pin to AIN mappings."
- default 0
- depends on TIVA_ADC1_SSE0_STEP7
-
-menuconfig TIVA_ADC1_SSE1
- bool "Enable and configure ADC1 SSE1"
- default n
- ---help---
- Select this Sample Sequencer for operation. There are 0-3,4-7 possible SSEs
- depending on how many ADC peripherals are available (4 per each ADC).
-
- Configuration variables:
- - trigger select
- - priority
- - input channel step assignment
-
-config TIVA_ADC1_SSE1_PRIORITY
- int "Conversion priority, must be a value from 0 to 3, no duplicates"
- default 0
- depends on TIVA_ADC1_SSE1
- ---help---
- Set the conversion priority for this SSE. Each ADC has 4 SSEs so the
- order in which they are serviced is determined by this value.
-config TIVA_ADC1_SSE1_TRIGGER
- int "Set the trigger source to start a SSE's conversion, see help for options"
- default 0
- depends on TIVA_ADC1_SSE1
- ---help---
- Set the trigger source. The following values correspond to the
- following triggers:
- - 0x0: Processor (default)
- - 0x1: *Analog Comparator 0
- - 0x2: *Analog Comparator 1
- - 0x3: *Analog Comparator 2
- - 0x4: External (GPIO Pins)
- - 0x5: Timer
- - 0x6: **PWM generator 0
- - 0x7: **PWM generator 1
- - 0x8: **PWM generator 2
- - 0x9: **PWM generator 3
- - 0xE: Never Trigger
- - 0xF: Always (continuously sample)
-
- * Comparators are unsupported
- ** PWM triggering requires additional setup at runtime - There is a special
- ADC IOCTL defined in the Tiva ADC driver for this purpose.
-
-menuconfig TIVA_ADC1_SSE1_STEP0
- bool "Enable and configure ADC1 SSE1 step 0"
- default n
- depends on TIVA_ADC1_SSE1
-
-config TIVA_ADC1_SSE1_STEP0_TS
- bool "This step will retrieve data from the on-chip temperature sensor."
- default n
- depends on TIVA_ADC1_SSE1_STEP0
-
-config TIVA_ADC1_SSE1_STEP0_AIN
- int "Set the input AIN. See datasheet for pin to AIN mappings."
- default 0
- depends on TIVA_ADC1_SSE1_STEP0
-
-menuconfig TIVA_ADC1_SSE1_STEP1
- bool "Enable and configure ADC1 SSE1 step 1"
- default n
- depends on TIVA_ADC1_SSE1
-
-config TIVA_ADC1_SSE1_STEP1_TS
- bool "This step will retrieve data from the on-chip temperature sensor."
- default n
- depends on TIVA_ADC1_SSE1_STEP1
-
-config TIVA_ADC1_SSE1_STEP1_AIN
- int "Set the input AIN. See datasheet for pin to AIN mappings."
- default 0
- depends on TIVA_ADC1_SSE1_STEP1
-
-menuconfig TIVA_ADC1_SSE1_STEP2
- bool "Enable and configure ADC1 SSE1 step 2"
- default n
- depends on TIVA_ADC1_SSE1
-
-config TIVA_ADC1_SSE1_STEP2_TS
- bool "This step will retrieve data from the on-chip temperature sensor."
- default n
- depends on TIVA_ADC1_SSE1_STEP2
-
-config TIVA_ADC1_SSE1_STEP2_AIN
- int "Set the input AIN. See datasheet for pin to AIN mappings."
- default 0
- depends on TIVA_ADC1_SSE1_STEP2
-
-menuconfig TIVA_ADC1_SSE1_STEP3
- bool "Enable and configure ADC1 SSE1 step 3"
- default n
- depends on TIVA_ADC1_SSE1
-
-config TIVA_ADC1_SSE1_STEP3_TS
- bool "This step will retrieve data from the on-chip temperature sensor."
- default n
- depends on TIVA_ADC1_SSE1_STEP3
-
-config TIVA_ADC1_SSE1_STEP3_AIN
- int "Set the input AIN. See datasheet for pin to AIN mappings."
- default 0
- depends on TIVA_ADC1_SSE1_STEP3
-
-menuconfig TIVA_ADC1_SSE2
- bool "Enable and configure ADC1 SSE2"
- default n
- ---help---
- Select this Sample Sequencer for operation. There are 0-3,4-7 possible SSEs
- depending on how many ADC peripherals are available (4 per each ADC).
-
- Configuration variables:
- - trigger select
- - priority
- - input channel step assignment
-
-config TIVA_ADC1_SSE2_PRIORITY
- int "Conversion priority, must be a value from 0 to 3, no duplicates"
- default 0
- depends on TIVA_ADC1_SSE2
- ---help---
- Set the conversion priority for this SSE. Each ADC has 4 SSEs so the
- order in which they are serviced is determined by this value.
-config TIVA_ADC1_SSE2_TRIGGER
- int "Set the trigger source to start a SSE's conversion, see help for options"
- default 0
- range 0 15
- depends on TIVA_ADC1_SSE2
- ---help---
- Set the trigger source. The following values correspond to the
- following triggers:
- - 0x0: Processor (default)
- - 0x1: *Analog Comparator 0
- - 0x2: *Analog Comparator 1
- - 0x3: *Analog Comparator 2
- - 0x4: External (GPIO Pins)
- - 0x5: Timer
- - 0x6: **PWM generator 0
- - 0x7: **PWM generator 1
- - 0x8: **PWM generator 2
- - 0x9: **PWM generator 3
- - 0xE: Never Trigger
- - 0xF: Always (continuously sample)
-
- * Comparators are unsupported
- ** PWM triggering requires additional setup at runtime - There is a special
- ADC IOCTL defined in the Tiva ADC driver for this purpose.
-
-menuconfig TIVA_ADC1_SSE2_STEP0
- bool "Enable and configure ADC1 SSE2 step 0"
- default n
- depends on TIVA_ADC1_SSE2
-
-config TIVA_ADC1_SSE2_STEP0_TS
- bool "This step will retrieve data from the on-chip temperature sensor."
- default n
- depends on TIVA_ADC1_SSE2_STEP0
-
-config TIVA_ADC1_SSE2_STEP0_AIN
- int "Set the input AIN. See datasheet for pin to AIN mappings."
- default 0
- depends on TIVA_ADC1_SSE2_STEP0
-
-menuconfig TIVA_ADC1_SSE2_STEP1
- bool "Enable and configure ADC1 SSE2 step 1"
- default n
- depends on TIVA_ADC1_SSE2
-
-config TIVA_ADC1_SSE2_STEP1_TS
- bool "This step will retrieve data from the on-chip temperature sensor."
- default n
- depends on TIVA_ADC1_SSE2_STEP1
-
-config TIVA_ADC1_SSE2_STEP1_AIN
- int "Set the input AIN. See datasheet for pin to AIN mappings."
- default 0
- depends on TIVA_ADC1_SSE2_STEP1
-
-menuconfig TIVA_ADC1_SSE2_STEP2
- bool "Enable and configure ADC1 SSE2 step 2"
- default n
- depends on TIVA_ADC1_SSE2
-
-config TIVA_ADC1_SSE2_STEP2_TS
- bool "This step will retrieve data from the on-chip temperature sensor."
- default n
- depends on TIVA_ADC1_SSE2_STEP2
-
-config TIVA_ADC1_SSE2_STEP2_AIN
- int "Set the input AIN. See datasheet for pin to AIN mappings."
- default 0
- depends on TIVA_ADC1_SSE2_STEP2
-
-menuconfig TIVA_ADC1_SSE2_STEP3
- bool "Enable and configure ADC1 SSE2 step 3"
- default n
- depends on TIVA_ADC1_SSE2
-
-config TIVA_ADC1_SSE2_STEP3_TS
- bool "This step will retrieve data from the on-chip temperature sensor."
- default n
- depends on TIVA_ADC1_SSE2_STEP3
-
-config TIVA_ADC1_SSE2_STEP3_AIN
- int "Set the input AIN. See datasheet for pin to AIN mappings."
- default 0
- depends on TIVA_ADC1_SSE2_STEP3
-
-menuconfig TIVA_ADC1_SSE3
- bool "Enable and configure ADC1 SSE3"
- default n
- ---help---
- Select this Sample Sequencer for operation. There are 0-3,4-7 possible SSEs
- depending on how many ADC peripherals are available (4 per each ADC).
-
- Configuration variables:
- - trigger select
- - priority
- - input channel step assignment
-
-config TIVA_ADC1_SSE3_PRIORITY
- int "Conversion priority, must be a value from 0 to 3, no duplicates"
- default 0
- depends on TIVA_ADC1_SSE3
- ---help---
- Set the conversion priority for this SSE. Each ADC has 4 SSEs so the
- order in which they are serviced is determined by this value.
-config TIVA_ADC1_SSE3_TRIGGER
- int "Set the trigger source to start a SSE's conversion, see help for options"
- default 0
- depends on TIVA_ADC1_SSE3
- ---help---
- Set the trigger source. The following values correspond to the
- following triggers:
- - 0x0: Processor (default)
- - 0x1: *Analog Comparator 0
- - 0x2: *Analog Comparator 1
- - 0x3: *Analog Comparator 2
- - 0x4: External (GPIO Pins)
- - 0x5: Timer
- - 0x6: **PWM generator 0
- - 0x7: **PWM generator 1
- - 0x8: **PWM generator 2
- - 0x9: **PWM generator 3
- - 0xE: Never Trigger
- - 0xF: Always (continuously sample)
-
- * Comparators are unsupported
- ** PWM triggering requires additional setup at runtime - There is a special
- ADC IOCTL defined in the Tiva ADC driver for this purpose.
-
- menuconfig TIVA_ADC1_SSE3_STEP0
- bool "Enable and configure ADC1 SSE3 step 0"
- default n
- depends on TIVA_ADC1_SSE3
-
- config TIVA_ADC1_SSE3_STEP0_TS
- bool "This step will retrieve data from the on-chip temperature sensor."
- default n
- depends on TIVA_ADC1_SSE3_STEP0
-
- config TIVA_ADC1_SSE3_STEP0_AIN
- int "Set the input AIN. See datasheet for pin to AIN mappings."
- default 0
- depends on TIVA_ADC1_SSE3_STEP0
-
-endif # TIVA_ADC1
+menu "ADC Configuration"
config TIVA_ADC_REGDEBUG
bool "Register level debug"
@@ -1809,7 +917,7 @@ config TIVA_DUMPPACKET
endmenu # Stellaris Ethernet Configuration
-menu "Tiva Ethernet Configuration"
+menu "Ethernet Configuration"
depends on ARCH_CHIP_TM4C
choice
diff --git a/nuttx/arch/arm/src/tiva/Make.defs b/nuttx/arch/arm/src/tiva/Make.defs
index a3f3c68a1..ff3cb347f 100644
--- a/nuttx/arch/arm/src/tiva/Make.defs
+++ b/nuttx/arch/arm/src/tiva/Make.defs
@@ -104,7 +104,8 @@ endif
endif
ifeq ($(CONFIG_TIVA_ADC),y)
-CHIP_CSRCS += tiva_adc.c
+CHIP_CSRCS += tiva_adclow.c
+CHIP_CSRCS += tiva_adclib.c
endif
ifeq ($(CONFIG_NET),y)
diff --git a/nuttx/arch/arm/src/tiva/chip/tiva_adc.h b/nuttx/arch/arm/src/tiva/chip/tiva_adc.h
index 52467df94..2b2dd131d 100644
--- a/nuttx/arch/arm/src/tiva/chip/tiva_adc.h
+++ b/nuttx/arch/arm/src/tiva/chip/tiva_adc.h
@@ -48,53 +48,53 @@
/* ADC register offsets *************************************************************/
-#define TIVA_ADC_ACTSS_OFFSET 0x00000000 /* ADC Active Sample Sequencer */
-#define TIVA_ADC_RIS_OFFSET 0x00000004 /* ADC Raw Interrupt Status */
-#define TIVA_ADC_IM_OFFSET 0x00000008 /* ADC Interrupt Mask */
-#define TIVA_ADC_ISC_OFFSET 0x0000000C /* ADC Interrupt Status and Clear */
-#define TIVA_ADC_OSTAT_OFFSET 0x00000010 /* ADC Overflow Status */
-#define TIVA_ADC_EMUX_OFFSET 0x00000014 /* ADC Event Multiplexer Select */
-#define TIVA_ADC_USTAT_OFFSET 0x00000018 /* ADC Underflow Status */
-#define TIVA_ADC_TSSEL_OFFSET 0x0000001C /* ADC Trigger Source Select */
-#define TIVA_ADC_SSPRI_OFFSET 0x00000020 /* ADC Sample Sequencer Priority */
-#define TIVA_ADC_SPC_OFFSET 0x00000024 /* ADC Sample Phase Control */
-#define TIVA_ADC_PSSI_OFFSET 0x00000028 /* ADC Processor Sample Sequence Initiate */
-#define TIVA_ADC_SAC_OFFSET 0x00000030 /* ADC Sample Averaging Control */
-#define TIVA_ADC_DCISC_OFFSET 0x00000034 /* ADC Digital Comparator Interrupt Status and Clear */
-#define TIVA_ADC_CTL_OFFSET 0x00000038 /* ADC Control */
-
-#define TIVA_ADC_SS_BASE 0x00000040 /* ADC Sample Sequence base address */
-#define TIVA_ADC_SSMUX_OFFSET 0x00000020 /* ADC Sample Sequence Input Multiplexer Select */
-#define TIVA_ADC_SSCTL_OFFSET 0x00000004 /* ADC Sample Sequence Control */
-#define TIVA_ADC_SSFIFO_OFFSET 0x00000008 /* ADC Sample Sequence Result FIFO */
-#define TIVA_ADC_SSFSTAT_OFFSET 0x0000000C /* ADC Sample Sequence FIFO Status */
-#define TIVA_ADC_SSOP_OFFSET 0x00000010 /* ADC Sample Sequence Operation */
-#define TIVA_ADC_SSDC_OFFSET 0x00000014 /* ADC Sample Sequence Digital Comparator Select */
-#define TIVA_ADC_SSEMUX_OFFSET 0x00000018 /* ADC Sample Sequence Extended Input Multiplexer Select */
-#define TIVA_ADC_SSTSH_OFFSET 0x0000001C /* ADC Sample Sequence Sample and Hold Time */
-
-#define TIVA_ADC_DCRIC_OFFSET 0x00000D00 /* ADC Digital Comparator Reset Initial Conditions */
-#define TIVA_ADC_DCCTL0_OFFSET 0x00000E00 /* ADC Digital Comparator Control 0 */
-#define TIVA_ADC_DCCTL1_OFFSET 0x00000E04 /* ADC Digital Comparator Control 1 */
-#define TIVA_ADC_DCCTL2_OFFSET 0x00000E08 /* ADC Digital Comparator Control 2 */
-#define TIVA_ADC_DCCTL3_OFFSET 0x00000E0C /* ADC Digital Comparator Control 3 */
-#define TIVA_ADC_DCCTL4_OFFSET 0x00000E10 /* ADC Digital Comparator Control 4 */
-#define TIVA_ADC_DCCTL5_OFFSET 0x00000E14 /* ADC Digital Comparator Control 5 */
-#define TIVA_ADC_DCCTL6_OFFSET 0x00000E18 /* ADC Digital Comparator Control 6 */
-#define TIVA_ADC_DCCTL7_OFFSET 0x00000E1C /* ADC Digital Comparator Control 7 */
-
-#define TIVA_ADC_DCCMP0_OFFSET 0x00000E40 /* ADC Digital Comparator Range 0 */
-#define TIVA_ADC_DCCMP1_OFFSET 0x00000E44 /* ADC Digital Comparator Range 1 */
-#define TIVA_ADC_DCCMP2_OFFSET 0x00000E48 /* ADC Digital Comparator Range 2 */
-#define TIVA_ADC_DCCMP3_OFFSET 0x00000E4C /* ADC Digital Comparator Range 3 */
-#define TIVA_ADC_DCCMP4_OFFSET 0x00000E50 /* ADC Digital Comparator Range 4 */
-#define TIVA_ADC_DCCMP5_OFFSET 0x00000E54 /* ADC Digital Comparator Range 5 */
-#define TIVA_ADC_DCCMP6_OFFSET 0x00000E58 /* ADC Digital Comparator Range 6 */
-#define TIVA_ADC_DCCMP7_OFFSET 0x00000E5C /* ADC Digital Comparator Range 7 */
-
-#define TIVA_ADC_PP_OFFSET 0x00000FC0 /* ADC Peripheral Properties */
-#define TIVA_ADC_PC_OFFSET 0x00000FC4 /* ADC Peripheral Configuration */
-#define TIVA_ADC_CC_OFFSET 0x00000FC8 /* ADC Clock Configuration */
+#define TIVA_ADC_ACTSS_OFFSET 0x000 /* ADC Active Sample Sequencer */
+#define TIVA_ADC_RIS_OFFSET 0x004 /* ADC Raw Interrupt Status */
+#define TIVA_ADC_IM_OFFSET 0x008 /* ADC Interrupt Mask */
+#define TIVA_ADC_ISC_OFFSET 0x00c /* ADC Interrupt Status and Clear */
+#define TIVA_ADC_OSTAT_OFFSET 0x010 /* ADC Overflow Status */
+#define TIVA_ADC_EMUX_OFFSET 0x014 /* ADC Event Multiplexer Select */
+#define TIVA_ADC_USTAT_OFFSET 0x018 /* ADC Underflow Status */
+#define TIVA_ADC_TSSEL_OFFSET 0x01c /* ADC Trigger Source Select */
+#define TIVA_ADC_SSPRI_OFFSET 0x020 /* ADC Sample Sequencer Priority */
+#define TIVA_ADC_SPC_OFFSET 0x024 /* ADC Sample Phase Control */
+#define TIVA_ADC_PSSI_OFFSET 0x028 /* ADC Processor Sample Sequence Initiate */
+#define TIVA_ADC_SAC_OFFSET 0x030 /* ADC Sample Averaging Control */
+#define TIVA_ADC_DCISC_OFFSET 0x034 /* ADC Digital Comparator Interrupt Status and Clear */
+#define TIVA_ADC_CTL_OFFSET 0x038 /* ADC Control */
+
+#define TIVA_ADC_SS_BASE 0x040 /* ADC Sample Sequence base address */
+#define TIVA_ADC_SSMUX_OFFSET 0x020 /* ADC Sample Sequence Input Multiplexer Select */
+#define TIVA_ADC_SSCTL_OFFSET 0x004 /* ADC Sample Sequence Control */
+#define TIVA_ADC_SSFIFO_OFFSET 0x008 /* ADC Sample Sequence Result FIFO */
+#define TIVA_ADC_SSFSTAT_OFFSET 0x00c /* ADC Sample Sequence FIFO Status */
+#define TIVA_ADC_SSOP_OFFSET 0x010 /* ADC Sample Sequence Operation */
+#define TIVA_ADC_SSDC_OFFSET 0x014 /* ADC Sample Sequence Digital Comparator Select */
+#define TIVA_ADC_SSEMUX_OFFSET 0x018 /* ADC Sample Sequence Extended Input Multiplexer Select */
+#define TIVA_ADC_SSTSH_OFFSET 0x01c /* ADC Sample Sequence Sample and Hold Time */
+
+#define TIVA_ADC_DCRIC_OFFSET 0xd00 /* ADC Digital Comparator Reset Initial Conditions */
+#define TIVA_ADC_DCCTL0_OFFSET 0xe00 /* ADC Digital Comparator Control 0 */
+#define TIVA_ADC_DCCTL1_OFFSET 0xe04 /* ADC Digital Comparator Control 1 */
+#define TIVA_ADC_DCCTL2_OFFSET 0xe08 /* ADC Digital Comparator Control 2 */
+#define TIVA_ADC_DCCTL3_OFFSET 0xe0c /* ADC Digital Comparator Control 3 */
+#define TIVA_ADC_DCCTL4_OFFSET 0xe10 /* ADC Digital Comparator Control 4 */
+#define TIVA_ADC_DCCTL5_OFFSET 0xe14 /* ADC Digital Comparator Control 5 */
+#define TIVA_ADC_DCCTL6_OFFSET 0xe18 /* ADC Digital Comparator Control 6 */
+#define TIVA_ADC_DCCTL7_OFFSET 0xe1c /* ADC Digital Comparator Control 7 */
+
+#define TIVA_ADC_DCCMP0_OFFSET 0xe40 /* ADC Digital Comparator Range 0 */
+#define TIVA_ADC_DCCMP1_OFFSET 0xe44 /* ADC Digital Comparator Range 1 */
+#define TIVA_ADC_DCCMP2_OFFSET 0xe48 /* ADC Digital Comparator Range 2 */
+#define TIVA_ADC_DCCMP3_OFFSET 0xe4c /* ADC Digital Comparator Range 3 */
+#define TIVA_ADC_DCCMP4_OFFSET 0xe50 /* ADC Digital Comparator Range 4 */
+#define TIVA_ADC_DCCMP5_OFFSET 0xe54 /* ADC Digital Comparator Range 5 */
+#define TIVA_ADC_DCCMP6_OFFSET 0xe58 /* ADC Digital Comparator Range 6 */
+#define TIVA_ADC_DCCMP7_OFFSET 0xe5c /* ADC Digital Comparator Range 7 */
+
+#define TIVA_ADC_PP_OFFSET 0xfc0 /* ADC Peripheral Properties */
+#define TIVA_ADC_PC_OFFSET 0xfc4 /* ADC Peripheral Configuration */
+#define TIVA_ADC_CC_OFFSET 0xfc8 /* ADC Clock Configuration */
/* ADC register addresses ***********************************************************/
@@ -329,22 +329,22 @@
/* Bit fields in the TIVA_ADC_ISC register. */
-#define ADC_ISC_SSE(n) (1 << ((n)*4))
-#define ADC_ISC_DCIN_SHIFT 20
-# define ADC_ISC_DCINSS3 (0x8) /* Digital Comparator Interrupt Status on SS3 */
-# define ADC_ISC_DCINSS2 (0x4) /* Digital Comparator Interrupt Status on SS2 */
-# define ADC_ISC_DCINSS1 (0x2) /* Digital Comparator Interrupt Status on SS1 */
-# define ADC_ISC_DCINSS0 (0x1) /* Digital Comparator Interrupt Status on SS0 */
-#define ADC_ISC_DMAIN_SHIFT 8
-# define ADC_ISC_DMAIN3 (0x8) /* SS3 DMA Interrupt Status and Clear */
-# define ADC_ISC_DMAIN2 (0x4) /* SS2 DMA Interrupt Status and Clear */
-# define ADC_ISC_DMAIN1 (0x2) /* SS1 DMA Interrupt Status and Clear */
-# define ADC_ISC_DMAIN0 (0x1) /* SS0 DMA Interrupt Status and Clear */
-#define ADC_ISC_IN_SHIFT 0
-# define ADC_ISC_IN3 (0x8) /* SS3 Interrupt Status and Clear */
-# define ADC_ISC_IN2 (0x4) /* SS2 Interrupt Status and Clear */
-# define ADC_ISC_IN1 (0x2) /* SS1 Interrupt Status and Clear */
-# define ADC_ISC_IN0 (0x1) /* SS0 Interrupt Status and Clear */
+#define ADC_ISC_SSE(n) (1 << ((n)*4))
+#define ADC_ISC_DCIN_SHIFT 20
+# define ADC_ISC_DCINSS3 (0x8) /* Digital Comparator Interrupt Status on SS3 */
+# define ADC_ISC_DCINSS2 (0x4) /* Digital Comparator Interrupt Status on SS2 */
+# define ADC_ISC_DCINSS1 (0x2) /* Digital Comparator Interrupt Status on SS1 */
+# define ADC_ISC_DCINSS0 (0x1) /* Digital Comparator Interrupt Status on SS0 */
+#define ADC_ISC_DMAIN_SHIFT 8
+# define ADC_ISC_DMAIN3 (0x8) /* SS3 DMA Interrupt Status and Clear */
+# define ADC_ISC_DMAIN2 (0x4) /* SS2 DMA Interrupt Status and Clear */
+# define ADC_ISC_DMAIN1 (0x2) /* SS1 DMA Interrupt Status and Clear */
+# define ADC_ISC_DMAIN0 (0x1) /* SS0 DMA Interrupt Status and Clear */
+#define ADC_ISC_IN_SHIFT 0
+# define ADC_ISC_IN3 (0x8) /* SS3 Interrupt Status and Clear */
+# define ADC_ISC_IN2 (0x4) /* SS2 Interrupt Status and Clear */
+# define ADC_ISC_IN1 (0x2) /* SS1 Interrupt Status and Clear */
+# define ADC_ISC_IN0 (0x1) /* SS0 Interrupt Status and Clear */
/* Bit fields in the TIVA_ADC_OSTAT register. */
@@ -355,20 +355,20 @@
/* Bit fields in the TIVA_ADC_EMUX register. */
-#define ADC_EMUX_SHIFT(n) (4 * (n)) /* SS EMUX Shift */
-#define ADC_EMUX_MASK(n) (0xF << ADC_EMUX_SHIFT(n)) /* SS EMUX Mask */
-# define ADC_EMUX_PROC (0x0) /* Processor (default) */
-# define ADC_EMUX_COMP0 (0x1) /* Analog Comparator 0 */
-# define ADC_EMUX_COMP1 (0x2) /* Analog Comparator 1 */
-# define ADC_EMUX_COMP2 (0x3) /* Analog Comparator 2 */
-# define ADC_EMUX_EXTERNAL (0x4) /* External (GPIO Pins) */
-# define ADC_EMUX_TIMER (0x5) /* Timer */
-# define ADC_EMUX_PWM0 (0x6) /* PWM generator 0 */
-# define ADC_EMUX_PWM1 (0x7) /* PWM generator 1 */
-# define ADC_EMUX_PWM2 (0x8) /* PWM generator 2 */
-# define ADC_EMUX_PWM3 (0x9) /* PWM generator 3 */
-# define ADC_EMUX_NEVER (0xE) /* Never Trigger */
-# define ADC_EMUX_ALWAYS (0xF) /* Always (continuously sample) */
+#define ADC_EMUX_SHIFT(n) (4 * (n)) /* SS EMUX Shift */
+#define ADC_EMUX_MASK(n) (0xF << ADC_EMUX_SHIFT(n)) /* SS EMUX Mask */
+# define ADC_EMUX_PROC (0x0) /* Processor (default) */
+# define ADC_EMUX_COMP0 (0x1) /* Analog Comparator 0 */
+# define ADC_EMUX_COMP1 (0x2) /* Analog Comparator 1 */
+# define ADC_EMUX_COMP2 (0x3) /* Analog Comparator 2 */
+# define ADC_EMUX_EXTERNAL (0x4) /* External (GPIO Pins) */
+# define ADC_EMUX_TIMER (0x5) /* Timer */
+# define ADC_EMUX_PWM0 (0x6) /* PWM generator 0 */
+# define ADC_EMUX_PWM1 (0x7) /* PWM generator 1 */
+# define ADC_EMUX_PWM2 (0x8) /* PWM generator 2 */
+# define ADC_EMUX_PWM3 (0x9) /* PWM generator 3 */
+# define ADC_EMUX_NEVER (0xe) /* Never Trigger */
+# define ADC_EMUX_ALWAYS (0xf) /* Always (continuously sample) */
/* Bit fields in the TIVA_ADC_USTAT register. */
@@ -380,18 +380,19 @@
/* Bit fields in the TIVA_ADC_TSSEL register. */
#define ADC_TSSEL_PS_SHIFT(n) (((n)+((n)+1))*4)
-# define ADC_TSSEL_PS_M (0x3) /* PWM module trigger select */
-# define ADC_TSSEL_PS_0 (0x0) /* Use PWM module 0 */
-# define ADC_TSSEL_PS_1 (0x1) /* Use PWM module 1 */
+#define ADC_TSSEL_PS_MASK(n) (0x3 << ADC_TSSEL_PS_SHIFT((n)))
+# define ADC_TSSEL_PS_M (0x3) /* PWM module trigger select */
+# define ADC_TSSEL_PS_0 (0x0) /* Use PWM module 0 */
+# define ADC_TSSEL_PS_1 (0x1) /* Use PWM module 1 */
/* Bit fields in the TIVA_ADC_SSPRI register. */
#define ADC_SSPRI_SHIFT(n) ((n) * 4) /* SSE priority mask */
#define ADC_SSPRI_MASK(n) (0x3 << ADC_SSPRI_SHIFT(n)) /* SSE priority mask */
-# define ADC_SSPRI_0 (0x0) /* SSE priority value 0 (highest) */
-# define ADC_SSPRI_1 (0x1) /* SSE priority value 1 (high) */
-# define ADC_SSPRI_2 (0x2) /* SSE priority value 2 (low) */
-# define ADC_SSPRI_3 (0x3) /* SSE priority value 3 (lowest) */
+# define ADC_SSPRI_0 (0x0) /* SSE priority value 0 (highest) */
+# define ADC_SSPRI_1 (0x1) /* SSE priority value 1 (high) */
+# define ADC_SSPRI_2 (0x2) /* SSE priority value 2 (low) */
+# define ADC_SSPRI_3 (0x3) /* SSE priority value 3 (lowest) */
/* Bit fields in the TIVA_ADC_SPC register. */
@@ -417,10 +418,12 @@
#define ADC_PSSI_GSYNC 0x80000000 /* Global Synchronize */
#define ADC_PSSI_SYNCWAIT 0x08000000 /* Synchronize Wait */
-#define ADC_PSSI_SS3 0x00000008 /* SS3 Initiate */
-#define ADC_PSSI_SS2 0x00000004 /* SS2 Initiate */
-#define ADC_PSSI_SS1 0x00000002 /* SS1 Initiate */
-#define ADC_PSSI_SS0 0x00000001 /* SS0 Initiate */
+
+#define ADC_PSSI_TRIG_MASK 0xf /* Enable triggering mask */
+# define ADC_PSSI_SS3 0x8 /* SS3 Initiate */
+# define ADC_PSSI_SS2 0x4 /* SS2 Initiate */
+# define ADC_PSSI_SS1 0x2 /* SS1 Initiate */
+# define ADC_PSSI_SS0 0x1 /* SS0 Initiate */
/* Bit fields in the TIVA_ADC_SAC register. */
@@ -456,28 +459,28 @@
#define ADC_SSMUX_MUX_SHIFT(n) ((n)*4) /* nth Sample Input Select */
#define ADC_SSMUX_MUX_MASK(n) (0xF << ADC_SSMUX_MUX_SHIFT(n))
-
/* Bit fields in the TIVA_ADC_SSCTL register. */
#define ADC_SSCTL_SHIFT(n) ((n)*4)
-#define ADC_SSCTL_TS (0x8) /* Sample Temp Sensor Select */
-#define ADC_SSCTL_IE (0x4) /* Sample Interrupt Enable */
-#define ADC_SSCTL_END (0x2) /* Sample is End of Sequence */
-#define ADC_SSCTL_D (0x1) /* Sample Differential Input Select */
+#define ADC_SSCTL_MASK(n) (0xF << ADC_SSCTL_SHIFT((n)))
+# define ADC_SSCTL_TS (0x8) /* Sample Temp Sensor Select */
+# define ADC_SSCTL_IE (0x4) /* Sample Interrupt Enable */
+# define ADC_SSCTL_END (0x2) /* Sample is End of Sequence */
+# define ADC_SSCTL_D (0x1) /* Sample Differential Input Select */
/* Bit fields in the TIVA_ADC_SSFIFO0 register. */
#define ADC_SSFIFO0_DATA_MASK 0x00000FFF /* Conversion Result Data */
-# define ADC_SSFIFO0_DATA_SHIFT 0
+# define ADC_SSFIFO0_DATA_SHIFT 0
/* Bit fields in the TIVA_ADC_SSFSTAT0 register. */
#define ADC_SSFSTAT0_HPTR_MASK 0x000000F0 /* FIFO Head Pointer */
-#define ADC_SSFSTAT_TPTR_MASK 0x0000000F /* FIFO Tail Pointer */
-# define ADC_SSFSTAT_HPTR_SHIFT 4
-# define ADC_SSFSTAT_TPTR_SHIFT 0
-#define ADC_SSFSTAT_FULL 0x00001000 /* FIFO Full */
-#define ADC_SSFSTAT_EMPTY 0x00000100 /* FIFO Empty */
+#define ADC_SSFSTAT_TPTR_MASK 0x0000000F /* FIFO Tail Pointer */
+# define ADC_SSFSTAT_HPTR_SHIFT 4
+# define ADC_SSFSTAT_TPTR_SHIFT 0
+#define ADC_SSFSTAT_FULL 0x00001000 /* FIFO Full */
+#define ADC_SSFSTAT_EMPTY 0x00000100 /* FIFO Empty */
/* Bit fields in the TIVA_ADC_SSOP0 register. */
@@ -517,21 +520,21 @@
/* Bit fields in the TIVA_ADC_SSTSH register. */
-#define ADC_SSTSH_SHIFT(n) ((n) * 4)
-#define ADC_SSTSH_MASK(n) (0xF << (ADC_SSTSH_SHIFT(n))) /* nth Sample and Hold Period Select */
-# define ADC_SSTH_SHOLD_4 (0x0) /* Sample and hold 4 ADC clocks */
-# define ADC_SSTH_SHOLD_8 (0x2) /* Sample and hold 8 ADC clocks */
-# define ADC_SSTH_SHOLD_16 (0x4) /* Sample and hold 16 ADC clocks */
-# define ADC_SSTH_SHOLD_32 (0x6) /* Sample and hold 32 ADC clocks */
-# define ADC_SSTH_SHOLD_64 (0x8) /* Sample and hold 64 ADC clocks */
-# define ADC_SSTH_SHOLD_128 (0xA) /* Sample and hold 128 ADC clocks */
-# define ADC_SSTH_SHOLD_256 (0xC) /* Sample and hold 256 ADC clocks */
-# define SSTSH_TSH_TS ADC_SSTH_SHOLD_4 /* Same and hold time for the temp sensor should be at least 16 ADC ticks */
+#define ADC_SSTSH_SHIFT(n) ((n) * 4)
+#define ADC_SSTSH_MASK(n) (0xf << (ADC_SSTSH_SHIFT(n))) /* nth Sample and Hold Period Select */
+# define ADC_SSTH_SHOLD_4 (0x0) /* Sample and hold 4 ADC clocks */
+# define ADC_SSTH_SHOLD_8 (0x2) /* Sample and hold 8 ADC clocks */
+# define ADC_SSTH_SHOLD_16 (0x4) /* Sample and hold 16 ADC clocks */
+# define ADC_SSTH_SHOLD_32 (0x6) /* Sample and hold 32 ADC clocks */
+# define ADC_SSTH_SHOLD_64 (0x8) /* Sample and hold 64 ADC clocks */
+# define ADC_SSTH_SHOLD_128 (0xa) /* Sample and hold 128 ADC clocks */
+# define ADC_SSTH_SHOLD_256 (0xc) /* Sample and hold 256 ADC clocks */
+# define SSTSH_TSH_TS ADC_SSTH_SHOLD_4 /* Same and hold time for the temp sensor should be at least 16 ADC ticks */
/* Bit fields in the TIVA_ADC_SSFIFO1 register. */
#define ADC_SSFIFO1_DATA_MASK 0x00000FFF /* Conversion Result Data */
-# define ADC_SSFIFO1_DATA_SHIFT 0
+# define ADC_SSFIFO1_DATA_SHIFT 0
/* Bit fields in the TIVA_ADC_SSFSTAT1 register. */
@@ -607,15 +610,15 @@
#define ADC_SSTSH2_TSH2_MASK 0x00000F00 /* 3rd Sample and Hold Period Select */
#define ADC_SSTSH2_TSH1_MASK 0x000000F0 /* 2nd Sample and Hold Period Select */
#define ADC_SSTSH2_TSH0_MASK 0x0000000F /* 1st Sample and Hold Period Select */
-# define ADC_SSTSH2_TSH3_SHIFT 12
-# define ADC_SSTSH2_TSH2_SHIFT 8
-# define ADC_SSTSH2_TSH1_SHIFT 4
-# define ADC_SSTSH2_TSH0_SHIFT 0
+# define ADC_SSTSH2_TSH3_SHIFT 12
+# define ADC_SSTSH2_TSH2_SHIFT 8
+# define ADC_SSTSH2_TSH1_SHIFT 4
+# define ADC_SSTSH2_TSH0_SHIFT 0
/* Bit fields in the TIVA_ADC_SSFIFO3 register. */
#define ADC_SSFIFO3_DATA_MASK 0x00000FFF /* Conversion Result Data */
-# define ADC_SSFIFO3_DATA_SHIFT 0
+# define ADC_SSFIFO3_DATA_SHIFT 0
/* Bit fields in the TIVA_ADC_SSFSTAT3 register. */
@@ -637,7 +640,7 @@
/* Bit fields in the TIVA_ADC_SSTSH3 register. */
#define ADC_SSTSH3_TSH0_MASK 0x0000000F /* 1st Sample and Hold Period Select */
-# define ADC_SSTSH3_TSH0_SHIFT 0
+# define ADC_SSTSH3_TSH0_SHIFT 0
/* Bit fields in the TIVA_ADC_DCRIC register. */
@@ -846,57 +849,57 @@
#define ADC_DCCMP0_COMP1_MASK 0x0FFF0000 /* Compare 1 */
#define ADC_DCCMP0_COMP0_MASK 0x00000FFF /* Compare 0 */
-# define ADC_DCCMP0_COMP1_SHIFT 16
-# define ADC_DCCMP0_COMP0_SHIFT 0
+# define ADC_DCCMP0_COMP1_SHIFT 16
+# define ADC_DCCMP0_COMP0_SHIFT 0
/* Bit fields in the TIVA_ADC_DCCMP1 register. */
#define ADC_DCCMP1_COMP1_MASK 0x0FFF0000 /* Compare 1 */
#define ADC_DCCMP1_COMP0_MASK 0x00000FFF /* Compare 0 */
-# define ADC_DCCMP1_COMP1_SHIFT 16
-# define ADC_DCCMP1_COMP0_SHIFT 0
+# define ADC_DCCMP1_COMP1_SHIFT 16
+# define ADC_DCCMP1_COMP0_SHIFT 0
/* Bit fields in the TIVA_ADC_DCCMP2 register. */
#define ADC_DCCMP2_COMP1_MASK 0x0FFF0000 /* Compare 1 */
#define ADC_DCCMP2_COMP0_MASK 0x00000FFF /* Compare 0 */
-# define ADC_DCCMP2_COMP1_SHIFT 16
-# define ADC_DCCMP2_COMP0_SHIFT 0
+# define ADC_DCCMP2_COMP1_SHIFT 16
+# define ADC_DCCMP2_COMP0_SHIFT 0
/* Bit fields in the TIVA_ADC_DCCMP3 register. */
#define ADC_DCCMP3_COMP1_MASK 0x0FFF0000 /* Compare 1 */
#define ADC_DCCMP3_COMP0_MASK 0x00000FFF /* Compare 0 */
-# define ADC_DCCMP3_COMP1_SHIFT 16
-# define ADC_DCCMP3_COMP0_SHIFT 0
+# define ADC_DCCMP3_COMP1_SHIFT 16
+# define ADC_DCCMP3_COMP0_SHIFT 0
/* Bit fields in the TIVA_ADC_DCCMP4 register. */
#define ADC_DCCMP4_COMP1_MASK 0x0FFF0000 /* Compare 1 */
#define ADC_DCCMP4_COMP0_MASK 0x00000FFF /* Compare 0 */
-# define ADC_DCCMP4_COMP1_SHIFT 16
-# define ADC_DCCMP4_COMP0_SHIFT 0
+# define ADC_DCCMP4_COMP1_SHIFT 16
+# define ADC_DCCMP4_COMP0_SHIFT 0
/* Bit fields in the TIVA_ADC_DCCMP5 register. */
#define ADC_DCCMP5_COMP1_MASK 0x0FFF0000 /* Compare 1 */
#define ADC_DCCMP5_COMP0_MASK 0x00000FFF /* Compare 0 */
-# define ADC_DCCMP5_COMP1_SHIFT 16
-# define ADC_DCCMP5_COMP0_SHIFT 0
+# define ADC_DCCMP5_COMP1_SHIFT 16
+# define ADC_DCCMP5_COMP0_SHIFT 0
/* Bit fields in the TIVA_ADC_DCCMP6 register. */
#define ADC_DCCMP6_COMP1_MASK 0x0FFF0000 /* Compare 1 */
#define ADC_DCCMP6_COMP0_MASK 0x00000FFF /* Compare 0 */
-# define ADC_DCCMP6_COMP1_SHIFT 16
-# define ADC_DCCMP6_COMP0_SHIFT 0
+# define ADC_DCCMP6_COMP1_SHIFT 16
+# define ADC_DCCMP6_COMP0_SHIFT 0
/* Bit fields in the TIVA_ADC_DCCMP7 register. */
#define ADC_DCCMP7_COMP1_MASK 0x0FFF0000 /* Compare 1 */
#define ADC_DCCMP7_COMP0_MASK 0x00000FFF /* Compare 0 */
-# define ADC_DCCMP7_COMP1_SHIFT 16
-# define ADC_DCCMP7_COMP0_SHIFT 0
+# define ADC_DCCMP7_COMP1_SHIFT 16
+# define ADC_DCCMP7_COMP0_SHIFT 0
/* Bit fields in the TIVA_ADC_PP register. */
@@ -906,9 +909,9 @@
#define ADC_PP_CH_MASK 0x000003F0 /* ADC Channel Count */
#define ADC_PP_MCR_MASK 0x0000000F /* Maximum Conversion Rate */
#define ADC_PP_MSR_MASK 0x0000000F /* Maximum ADC Sample Rate */
-# define ADC_PP_RSL_SHIFT 18
-# define ADC_PP_DC_SHIFT 10
-# define ADC_PP_CH_SHIFT 4
+# define ADC_PP_RSL_SHIFT 18
+# define ADC_PP_DC_SHIFT 10
+# define ADC_PP_CH_SHIFT 4
#define ADC_PP_APSHT 0x01000000 /* Application-Programmable Sample-and-Hold Time */
#define ADC_PP_TS 0x00800000 /* Temperature Sensor */
#define ADC_PP_TYPE_SAR 0x00000000 /* SAR */
@@ -933,11 +936,11 @@
/* Bit fields in the TIVA_ADC_CC register. */
-#define ADC_CC_CLKDIV_MASK (0x3F0) /* PLL VCO Clock Divisor */
-#define ADC_CC_CS_MASK (0x00F) /* ADC Clock Source */
+#define ADC_CC_CLKDIV_MASK (0x3F0) /* PLL VCO Clock Divisor */
+#define ADC_CC_CS_MASK (0x00F) /* ADC Clock Source */
# define ADC_CC_CLKDIV_SHIFT 4
-#define ADC_CC_CS_SYSPLL (0x000) /* PLL VCO divided by CLKDIV */
-#define ADC_CC_CS_PIOSC (0x001) /* PIOSC */
-#define ADC_CC_CS_MOSC (0x002) /* MOSC */
+#define ADC_CC_CS_SYSPLL (0x000) /* PLL VCO divided by CLKDIV */
+#define ADC_CC_CS_PIOSC (0x001) /* PIOSC */
+#define ADC_CC_CS_MOSC (0x002) /* MOSC */
#endif // __ARCH_ARM_SRC_TIVA_CHIP_TIVA_ADC_H
diff --git a/nuttx/arch/arm/src/tiva/tiva_adc.c b/nuttx/arch/arm/src/tiva/tiva_adc.c
deleted file mode 100644
index 26f3b6890..000000000
--- a/nuttx/arch/arm/src/tiva/tiva_adc.c
+++ /dev/null
@@ -1,2820 +0,0 @@
-/****************************************************************************
- * arch/arm/src/tiva/tiva_adc.c
- *
- * Copyright (C) 2015 TRD2 Inc. All rights reserved.
- * Author: Calvin Maguranis <calvin.maguranis@trd2inc.com>
- *
- * References:
- *
- * TM4C123GH6PM Series Data Sheet
- * TI Tivaware driverlib ADC sample code.
- *
- * The Tivaware sample code has a BSD compatible license that requires this
- * copyright notice:
- *
- * Copyright (c) 2005-2014 Texas Instruments Incorporated. All rights reserved.
- * Software License Agreement
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the
- * distribution.
- *
- * Neither the name of Texas Instruments Incorporated nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * This is part of revision 2.1.0.12573 of the Tiva Peripheral Driver Library.
- *****************************************************************************/
-
-/* Keep in mind that for every step there should be another entry in the
- * CONFIG_ADC_FIFOSIZE value.
- * e.g. if there are 12 steps in use; CONFIG_ADC_FIFOSIZE = 12+1 = 13
- * if there are 3 steps in use; CONFIG_ADC_FIFOSIZE = 3+1 = 4
- */
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <sys/types.h>
-#include <sys/ioctl.h>
-
-#include <stdio.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <semaphore.h>
-#include <errno.h>
-#include <debug.h>
-#include <assert.h>
-
-#include <arch/board/board.h>
-
-#include <nuttx/arch.h>
-#include <nuttx/wqueue.h>
-#include <nuttx/analog/adc.h>
-
-#include "up_internal.h"
-#include "up_arch.h"
-
-#include "chip.h"
-
-#include "tiva_gpio.h"
-#include "tiva_adc.h"
-#include "chip/tiva_pinmap.h"
-#include "chip/tiva_syscontrol.h"
-#include "chip/tiva_adc.h"
-
-#if defined (CONFIG_TIVA_ADC0) || defined (CONFIG_TIVA_ADC1)
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/* Configuration ************************************************************/
-
-#ifndef CONFIG_TIVA_ADC_CLOCK
-# define CONFIG_TIVA_ADC_CLOCK TIVA_ADC_CLOCK_MIN
-#endif
-
-#ifdef CONFIG_TIVA_ADC_VREF
-# ifndef CONFIG_ARCH_CHIP_TM4C129
-# error Voltage reference selection only supported in TM4C129 parts
-# endif
-#endif
-
-#ifdef CONFIG_TIVA_ADC_ALT_CLK
-# warning CONFIG_TIVA_ADC_ALT_CLK unsupported.
-#endif
-
-/* Are we using interrupt-based triggering (opposed to SW triggering)? Then work
- * queues are required.
- */
-
-#if (CONFIG_TIVA_ADC0_SSE0_TRIGGER > 0) || (CONFIG_TIVA_ADC0_SSE1_TRIGGER > 0) || \
- (CONFIG_TIVA_ADC0_SSE2_TRIGGER > 0) || (CONFIG_TIVA_ADC0_SSE3_TRIGGER > 0) || \
- (CONFIG_TIVA_ADC0_SSE0_TRIGGER > 0) || (CONFIG_TIVA_ADC0_SSE1_TRIGGER > 0) || \
- (CONFIG_TIVA_ADC0_SSE2_TRIGGER > 0) || (CONFIG_TIVA_ADC0_SSE3_TRIGGER > 0)
-# define TIVA_ADC_HAVE_INTERRUPTS 1
-#endif
-
-#ifdef TIVA_ADC_HAVE_INTERRUPTS
-# ifndef CONFIG_SCHED_WORKQUEUE
-# error Work queue support is required (CONFIG_SCHED_WORKQUEUE) for ADC interrupts
-# endif
-# ifndef CONFIG_SCHED_HPWORK
-# error High priority worker threads is required (CONFIG_SCHED_HPWORK) for ADC interrupts
-# endif
-#endif
-
-
-#ifndef CONFIG_DEBUG
-# undef CONFIG_TIVA_ADC_REGDEBUG
-#endif
-
-
-/* Misc utility defines *****************************************************/
-
-#define TIVA_ADC_ENABLE true
-#define TIVA_ADC_DISABLE false
-
-#define TIVA_ADC_RESOLUTION 4095
-
-#ifdef CONFIG_ARCH_CHIP_TM4C123
-# define TIVA_ADC_CLOCK_MAX (16000000)
-# define TIVA_ADC_CLOCK_MIN (16000000)
-#elif CONFIG_ARCH_CHIP_TM4C129
-# define TIVA_ADC_CLOCK_MAX (32000000)
-# define TIVA_ADC_CLOCK_MIN (16000000)
-#else
-# error TIVA_ADC_CLOCK: unsupported architecture
-#endif
-
-/* Allow the same function call to be used for sample rate */
-
-#ifdef CONFIG_ARCH_CHIP_TM4C123
-# define TIVA_ADC_SAMPLE_RATE_SLOWEST (ADC_PC_SR_125K)
-# define TIVA_ADC_SAMPLE_RATE_SLOW (ADC_PC_SR_250K)
-# define TIVA_ADC_SAMPLE_RATE_FAST (ADC_PC_SR_500K)
-# define TIVA_ADC_SAMPLE_RATE_FASTEST (ADC_PC_SR_1M)
-#elif CONFIG_ARCH_CHIP_TM4C129
-# define TIVA_ADC_SAMPLE_RATE_SLOWEST (ADC_PC_MCR_1_8)
-# define TIVA_ADC_SAMPLE_RATE_SLOW (ADC_PC_MCR_1_4)
-# define TIVA_ADC_SAMPLE_RATE_FAST (ADC_PC_MCR_1_2)
-# define TIVA_ADC_SAMPLE_RATE_FASTEST (ADC_PC_MCR_FULL)
-#else
-# error TIVA_ADC_SAMPLE_RATE: unsupported architecture
-#endif
-
-/* Utility macros ***********************************************************/
-
-/* PWM trigger support definitions ******************************************/
-
-/* Decodes the PWM generator and module from trigger and converts
- * to the TSSEL_PS register
- */
-
-#define ADC_TRIG_PWM_CFG(t) \
- (1<<(ADC_TSSEL_PS_SHIFT(ADC_TRIG_gen(t))))
-
-/* ADC support definitions **************************************************/
-
-#define ADC_CHN_AIN(n) GPIO_ADC_AIN##n
-#define TIVA_ADC_PIN(n) ADC_CHN_AIN(n)
-
-#define SSE_PROC_TRIG(n) (1 << (n))
-#define SSE_PROC_TRIG_ALL (0xF)
-
-#define SSE_IDX(a,s) (((a)*SSE_PER_BASE) + (s))
-
-#define MAX_NORMAL_CHN 15
-#define BASE_PER_ADC 2
-#define SSE_PER_BASE 4
-#define SSE_MAX_STEP 8
-#define NUM_SSE(n) (sizeof(n)/sizeof(n[0]))
-
-#define GET_AIN(a,s,c) (uint8_t)((getreg32( \
- TIVA_ADC_BASE(a)+TIVA_ADC_SSMUX(s)) & ADC_SSMUX_MUX_MASK(c)) >> ADC_SSMUX_MUX_SHIFT(c))
-
-#define ADC_SSE_STEP_NULL 0xFF
-
-#define CLOCK_CONFIG(div, src) \
- ( ((((div) << ADC_CC_CLKDIV_SHIFT) & ADC_CC_CLKDIV_MASK) | \
- ((src) & ADC_CC_CS_MASK)) & (ADC_CC_CLKDIV_MASK + ADC_CC_CS_MASK) )
-
-#define SEM_PROCESS_PRIVATE 0
-#define SEM_PROCESS_SHARED 1
-
-/* Debug ********************************************************************/
-
-#ifndef CONFIG_DEBUG
-# undef CONFIG_TIVA_ADC_REGDEBUG
-#endif
-
-/* ADC event trace logic. NOTE: trace uses the internal, non-standard, low-level
- * debug interface syslog() but does not require that any other debug
- * is enabled.
- */
-
-#ifndef CONFIG_ADC_TRACE
-# define tiva_adc_tracereset(p)
-# define tiva_adc_tracenew(p,s)
-# define tiva_adc_traceevent(p,e,a)
-# define tiva_adc_tracedump(p)
-#endif
-
-#ifndef CONFIG_ADC_NTRACE
-# define CONFIG_ADC_NTRACE 32
-#endif
-
-/****************************************************************************
- * Public Functions
- * **************************************************************************/
-
-/* Upper level ADC driver ***************************************************/
-
-static void tiva_adc_reset(struct adc_dev_s *dev);
-static int tiva_adc_setup(struct adc_dev_s *dev);
-static void tiva_adc_shutdown(struct adc_dev_s *dev);
-static void tiva_adc_rxint(struct adc_dev_s *dev, bool enable);
-static int tiva_adc_ioctl(struct adc_dev_s *dev, int cmd, unsigned long arg);
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-/* ADC lower half device operations */
-
-static const struct adc_ops_s g_adcops =
-{
- .ao_reset = tiva_adc_reset,
- .ao_setup = tiva_adc_setup,
- .ao_shutdown = tiva_adc_shutdown,
- .ao_rxint = tiva_adc_rxint,
- .ao_ioctl = tiva_adc_ioctl,
-};
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/* tracks overall ADC peripherals one-time initialization state */
-struct tiva_adc_state_s
-{
- bool init[BASE_PER_ADC];
- bool sse[BASE_PER_ADC * SSE_PER_BASE];
-};
-
-struct tiva_adc_s
-{
- struct adc_dev_s *dev;
- bool ena; /* Operation state */
- uint8_t devno; /* ADC device number */
- struct tiva_adc_sse_s *sse[SSE_PER_BASE]; /* Sample sequencer operation
- * state */
-#ifdef CONFIG_TIVA_ADC_REGDEBUG
- /* Debug stuff */
-
- bool wrlast; /* Last was a write */
- uintptr_t addrlast; /* Last address */
- uint32_t vallast; /* Last value */
- int ntimes; /* Number of times */
-#endif /* CONFIG_TIVA_ADC_REGDEBUG */
-};
-
-struct tiva_adc_sse_s
-{
- struct tiva_adc_s *adc; /* Parent peripheral */
-#ifdef TIVA_ADC_HAVE_INTERRUPTS
- sem_t exclsem; /* Mutual exclusion semaphore */
- struct work_s work; /* Supports the interrupt handling "bottom half" */
-#endif
- bool ena; /* Sample sequencer operation state */
- uint32_t irq; /* SSE interrupt vectors */
- uint8_t num; /* SSE number */
-};
-
-/****************************************************************************
- * Private Function Definitions
- ****************************************************************************/
-
-/* Debug ADC functions **********************************************/
-
-#if defined(CONFIG_TIVA_ADC_REGDEBUG) && defined(CONFIG_DEBUG)
-static bool tiva_adc_checkreg(struct tiva_adc_s *priv, bool wr,
- uint32_t regval, uintptr_t address);
-#endif
-
-#ifdef CONFIG_TIVA_ADC_REGDEBUG
-static void tiva_adc_modifyreg(struct tiva_adc_s *priv, unsigned int addr,
- uint32_t clearbits, uint32_t setbits);
-#else
-# define tiva_adc_modifyreg(priv,addr,clearbits,setbits) modifyreg32(addr,clearbits,setbits)
-#endif
-
-/* TM4C-specific ADC functions **********************************************/
-
-/* Common peripheral level */
-
-static int adc_state(struct tiva_adc_s *adc, bool state);
-static void adc_clock(uint32_t freq);
-#ifdef CONFIG_ARCH_CHIP_TM4C129
-static void adc_vref(uint8_t vref);
-#endif
-#ifdef CONFIG_TIVA_ADC_INTERRUPTS
-static void tiva_adc_read(void *arg);
-#endif
-
-/* Peripheral (base) level */
-
-static void adc_sample_rate(uint8_t rate);
-static void adc_proc_trig(struct tiva_adc_s *adc, uint8_t sse_mask);
-static uint32_t adc_int_status(struct tiva_adc_s *adc);
-
-/* Sample Sequencer (SSE) level */
-
-static void sse_state(struct tiva_adc_s *adc, uint8_t sse, bool state);
-static void sse_trigger(struct tiva_adc_s *adc, uint8_t sse, uint32_t trigger);
-#ifdef CONFIG_EXPERIMENTAL
-static void sse_pwm_trig_ioctl(struct tiva_adc_s *adc, uint8_t sse, uint32_t cfg);
-#endif
-static int sse_data(struct tiva_adc_s *adc, uint8_t sse);
-static void sse_priority(struct tiva_adc_s *adc, uint8_t sse, uint8_t priority);
-
-static void sse_int_state(struct tiva_adc_s *adc, uint8_t sse, bool state);
-static bool sse_int_status(struct tiva_adc_s *adc, uint8_t sse);
-static void sse_clear_int(struct tiva_adc_s *adc, uint8_t sse);
-
-static void sse_register_chn(struct tiva_adc_s *adc, uint8_t sse, uint8_t chn,
- uint32_t ain);
-static void sse_differential(struct tiva_adc_s *adc, uint8_t sse, uint8_t chn,
- uint32_t diff);
-#ifdef CONFIG_EXPERIMENTAL
-static void sse_sample_hold_time(struct tiva_adc_s *adc, uint8_t sse,
- uint8_t chn, uint32_t shold);
-#endif
-static void sse_step_cfg(struct tiva_adc_s *adc, uint8_t sse, uint8_t chn,
- uint8_t cfg);
-
-/* Helper functions *********************************************************/
-
-#ifdef CONFIG_TIVA_ADC0
-static void tiva_adc0_sse_init(void);
-static void tiva_adc0_assign_channels(void);
-# ifdef TIVA_ADC_HAVE_INTERRUPTS
-static void tiva_adc0_assign_interrupts(void);
-# endif
-# ifdef CONFIG_TIVA_ADC0_SSE0
-static void adc0_sse0_chn_cfg(void);
-# ifdef TIVA_ADC_HAVE_INTERRUPTS
-static void adc0_sse0_interrupt(int irq, void *context);
-# endif
-# endif
-# ifdef CONFIG_TIVA_ADC0_SSE1
-static void adc0_sse1_chn_cfg(void);
-# ifdef TIVA_ADC_HAVE_INTERRUPTS
-static void adc0_sse1_interrupt(int irq, void *context);
-# endif
-# endif
-# ifdef CONFIG_TIVA_ADC0_SSE2
-static void adc0_sse2_chn_cfg(void);
-# ifdef TIVA_ADC_HAVE_INTERRUPTS
-static void adc0_sse2_interrupt(int irq, void *context);
-# endif
-# endif
-# ifdef CONFIG_TIVA_ADC0_SSE3
-static void adc0_sse3_chn_cfg(void);
-# ifdef TIVA_ADC_HAVE_INTERRUPTS
-static void adc0_sse3_interrupt(int irq, void *context);
-# endif
-# endif
-#endif
-
-#ifdef CONFIG_TIVA_ADC1
-static void tiva_adc1_sse_init(void);
-static void tiva_adc1_assign_channels(void);
-# ifdef TIVA_ADC_HAVE_INTERRUPTS
-static void tiva_adc1_assign_interrupts(void);
-# endif
-# ifdef CONFIG_TIVA_ADC1_SSE0
-static void adc1_sse0_chn_cfg(void);
-# ifdef TIVA_ADC_HAVE_INTERRUPTS
-static void adc1_sse0_interrupt(int irq, void *context);
-# endif
-# endif
-# ifdef CONFIG_TIVA_ADC1_SSE1
-static void adc1_sse1_chn_cfg(void);
-# ifdef TIVA_ADC_HAVE_INTERRUPTS
-static void adc1_sse1_interrupt(int irq, void *context);
-# endif
-# endif
-# ifdef CONFIG_TIVA_ADC1_SSE2
-static void adc1_sse2_chn_cfg(void);
-# ifdef TIVA_ADC_HAVE_INTERRUPTS
-static void adc1_sse2_interrupt(int irq, void *context);
-# endif
-# endif
-# ifdef CONFIG_TIVA_ADC1_SSE3
-static void adc1_sse3_chn_cfg(void);
-# ifdef TIVA_ADC_HAVE_INTERRUPTS
-static void adc1_sse3_interrupt(int irq, void *context);
-# endif
-# endif
-#endif
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/* Tracks overall peripheral state */
-
-static struct tiva_adc_state_s adc_common =
-{
- .init =
- {
- false,
- false
- },
- .sse =
- {
- false,
- false,
- false,
- false,
- false,
- false,
- false,
- false
- },
-};
-
-#ifdef CONFIG_TIVA_ADC0
-
-/* ADC device instance 0 */
-
-static struct adc_dev_s g_adcdev0;
-static struct tiva_adc_s adc0;
-# ifdef CONFIG_TIVA_ADC0_SSE0
-static struct tiva_adc_sse_s sse00;
-# endif
-# ifdef CONFIG_TIVA_ADC0_SSE1
-static struct tiva_adc_sse_s sse01;
-# endif
-# ifdef CONFIG_TIVA_ADC0_SSE2
-static struct tiva_adc_sse_s sse02;
-# endif
-# ifdef CONFIG_TIVA_ADC0_SSE3
-static struct tiva_adc_sse_s sse03;
-# endif
-#endif
-
-#ifdef CONFIG_TIVA_ADC1
-
-/* ADC device instance 1 */
-
-static struct adc_dev_s g_adcdev1;
-static struct tiva_adc_s adc1;
-# ifdef CONFIG_TIVA_ADC1_SSE0
-static struct tiva_adc_sse_s sse10;
-# endif
-# ifdef CONFIG_TIVA_ADC1_SSE1
-static struct tiva_adc_sse_s sse11;
-# endif
-# ifdef CONFIG_TIVA_ADC1_SSE2
-static struct tiva_adc_sse_s sse12;
-# endif
-# ifdef CONFIG_TIVA_ADC1_SSE3
-static struct tiva_adc_sse_s sse13;
-# endif
-#endif
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: tiva_adc_reset
- *
- * Description:
- * Reset the ADC device. Called early to initialize the hardware. This is
- * called before tiva_adc_setup() and on error conditions.
- *
- ****************************************************************************/
-
-static void tiva_adc_reset(struct adc_dev_s *dev)
-{
- struct tiva_adc_s *priv = (struct tiva_adc_s *)dev->ad_priv;
-
- avdbg("Resetting...\n");
-
- /* Only if ADCs are active do we run the reset routine: - disable ADC
- * interrupts - clear interrupt bits - disable all active sequences
- * Otherwise, if the peripheral is inactive, perform no operations since
- * register access to a peripheral that is not active will result in a
- * segmentation fault.
- */
-
- if (priv->ena)
- {
- tiva_adc_rxint(dev, TIVA_ADC_DISABLE);
- uint8_t s;
- for (s = 0; s < SSE_PER_BASE; ++s)
- {
- if (adc_common.sse[SSE_IDX(priv->devno, s)])
- {
- sse_state(priv, s, TIVA_ADC_DISABLE);
- }
- }
- }
-}
-
-/****************************************************************************
- * Name: tiva_adc_setup
- *
- * Description:
- * Configure the ADC. This method is called the first time that the ADC
- * device is opened. This will occur when the port is first opened.
- * this setup includes configuring and attaching ADC interrupts. Interrupts
- * are all disabled upon return.
- *
- * Returned Value:
- * Non negative value on success; negative value on failure.
- *
- ****************************************************************************/
-
-static int tiva_adc_setup(struct adc_dev_s *dev)
-{
- avdbg("Setup\n");
-
- /* Only if ADCs are active do we run the reset routine: - enable ADC
- * interrupts - clear interrupt bits - enable all active sequences - register
- * triggers and respective interrupt handlers Otherwise, if the peripheral is
- * inactive, perform no operations since register access to a peripheral that
- * is not active will result in a segmentation fault.
- */
-
- struct tiva_adc_s *priv = (struct tiva_adc_s *)dev->ad_priv;
- uint8_t s = 0;
- for (s = 0; s < SSE_PER_BASE; ++s)
- {
- if (adc_common.sse[SSE_IDX(priv->devno, s)])
- {
- sse_state(priv, s, true);
- }
- }
-
- tiva_adc_rxint(dev, false);
- return OK;
-}
-
-/****************************************************************************
- * Name: tiva_adc_shutdown
- *
- * Description:
- * Disable the ADC. This method is called when the ADC device is closed.
- * This method reverses the operation the setup method.
- *
- ****************************************************************************/
-
-static void tiva_adc_shutdown(struct adc_dev_s *dev)
-{
- struct tiva_adc_s *priv = (struct tiva_adc_s *)dev->ad_priv;
-
- avdbg("Shutdown\n");
-
- /* Reset the ADC peripheral */
-
- tiva_adc_reset(dev);
-
- uint8_t s = 0;
- for (s = 0; s < SSE_PER_BASE; ++s)
- {
- if (adc_common.sse[SSE_IDX(priv->devno, s)])
- {
- /* Disable ADC interrupts at the level of the AIC */
-
- up_disable_irq(priv->sse[s]->irq);
-
- /* Then detach the ADC interrupt handler. */
-
- irq_detach(priv->sse[s]->irq);
- }
- }
-}
-
-/****************************************************************************
- * Name: tiva_adc_rxint
- *
- * Description:
- * Call to enable or disable RX interrupts
- *
- * Input Parameters:
- * enable - the enable state of interrupts for this device
- *
- ****************************************************************************/
-
-static void tiva_adc_rxint(struct adc_dev_s *dev, bool enable)
-{
- struct tiva_adc_s *priv = (struct tiva_adc_s *)dev->ad_priv;
-
- avdbg("rx enable=%d\n", enable);
-
- uint8_t s = 0;
- for (s = 0; s < SSE_PER_BASE; ++s)
- {
- uint32_t trigger =
- (tiva_adc_getreg(priv, TIVA_ADC_EMUX(priv->devno)) >> s) & 0xF;
- if (adc_common.sse[SSE_IDX(priv->devno, s)] && (trigger > 0))
- {
- sse_int_state(priv, s, enable);
- }
- }
-}
-
-/****************************************************************************
- * Name: tiva_adc_ioctl
- *
- * Description:
- * All ioctl calls will be routed through this method.
- *
- * Input Parameters:
- * cmd - ADC ioctl command
- * arg - argument for the ioctl command
- *
- * Returned Value:
- * Non negative value on success; negative value on failure.
- *
- ****************************************************************************/
-
-static int tiva_adc_ioctl(struct adc_dev_s *dev, int cmd, unsigned long arg)
-{
- struct tiva_adc_s *priv = (struct tiva_adc_s *)dev->ad_priv;
- int ret = OK;
- uint32_t regval = 0;
- uint8_t sse = 0;
-
- avdbg("cmd=%d arg=%ld\n", cmd, arg);
-
- switch (cmd)
- {
- /* Software trigger */
-
- case ANIOC_TRIGGER:
-
- sse = (uint8_t) arg;
-
- /* start conversion and read to buffer */
-
- adc_proc_trig(priv, (uint8_t) SSE_PROC_TRIG(sse));
- regval = adc_int_status(priv) & (1 << sse);
- while (!regval)
- {
- regval = adc_int_status(priv) & (1 << sse);
- }
-
- sse_clear_int(priv, sse);
- sse_data(priv, sse);
- break;
-
- /* PWM triggering */
-
-#warning Missing Logic
-
- /* TODO: Needs to be tested */
-
-#ifdef CONFIG_EXPERIMENTAL
-
- case TIVA_ADC_PWM_TRIG_IOCTL:
-
- /* Verify input SSE trigger is a PWM trigger */
-
- sse = (uint8_t)(arg & 0x2);
- regval = (tiva_adc_getreg(priv, (TIVA_ADC_EMUX(adc->devno))) >>
- ADC_EMUX_SHIFT(sse)) & ADC_EMUX_MASK(sse);
-
- if ((regval == ADC_EMUX_PWM0) ||
- (regval == ADC_EMUX_PWM1) ||
- (regval == ADC_EMUX_PWM2) ||
- (regval == ADC_EMUX_PWM3))
- {
- sse_pwm_trig_ioctl(priv, sse, (uint32_t)(arg&0xFFFFFFFC));
- }
-
- break;
-
-#endif
-
-#warning Missing Logic
-
- /* Unsupported or invalid command */
-
- default:
- ret = -ENOTTY;
- break;
- }
-
- return ret;
-}
-
-/****************************************************************************
- * Name: tiva_adc_read
- *
- * Description:
- * This function executes on the worker thread. It is scheduled by
- * sam_adc_interrupt whenever any enabled event occurs. All interrupts
- * are disabled when this function runs. tiva_adc_read will
- * re-enable interrupts when it completes processing all pending events.
- *
- * Input Parameters
- * arg - The ADC SSE data structure cast to (void *)
- *
- * Returned Value:
- * None
- *
- ****************************************************************************/
-
-static void tiva_adc_read(void *arg)
-{
- struct tiva_adc_sse_s *sse = (struct tiva_adc_sse_s *)arg;
- uint32_t data = 0;
- uint8_t fifo_count = 0;
-
- /* Get exclusive access to the driver data structure */
-
- tiva_adc_lock(sse->adc, sse->num);
-
- /* Get sampled data */
-
- while (!(tiva_adc_getreg(&adc0, TIVA_ADC_BASE(0) + TIVA_ADC_SSFSTAT(0)) &
- ADC_SSFSTAT_EMPTY) && fifo_count < SSE_MAX_STEP)
- {
- data = tiva_adc_getreg(&adc0, TIVA_ADC_BASE(0) + TIVA_ADC_SSFIFO(0));
- (void)adc_receive(adc0.dev, GET_AIN(0, 0, fifo_count), data);
- ++fifo_count;
- }
-
- /* Exit, re-enabling ADC interrupts */
-
- sse_int_state(&adc0, 0, TIVA_ADC_ENABLE);
-
- /* Release our lock on the ADC structure */
-
- tiva_adc_unlock(sse->adc, sse->num);
-}
-
-/****************************************************************************
- * Register Operations
- ****************************************************************************/
-
-#ifdef CONFIG_TIVA_ADC_REGDEBUG
-
-/****************************************************************************
- * Name: tiva_adc_checkreg
- *
- * Description:
- * Check if the current register access is a duplicate of the preceding.
- *
- * Input Parameters:
- * regval - The value to be written
- * address - The address of the register to write to
- *
- * Returned Value:
- * true: This is the first register access of this type.
- * flase: This is the same as the preceding register access.
- *
- ****************************************************************************/
-
-static bool tiva_adc_checkreg(struct tiva_adc_s *priv, bool wr,
- uint32_t regval, uintptr_t address)
-{
- if (wr == priv->wrlast && /* Same kind of access? */
- regval == priv->vallast && /* Same value? */
- address == priv->addrlast) /* Same address? */
- {
- /* Yes, then just keep a count of the number of times we did this. */
-
- priv->ntimes++;
- return false;
- }
- else
- {
- /* Did we do the previous operation more than once? */
-
- if (priv->ntimes > 0)
- {
- /* Yes... show how many times we did it */
-
- lldbg("...[Repeats %d times]...\n", priv->ntimes);
- }
-
- /* Save information about the new access */
-
- priv->wrlast = wr;
- priv->vallast = regval;
- priv->addrlast = address;
- priv->ntimes = 0;
- }
-
- /* Return true if this is the first time that we have done this operation */
-
- return true;
-}
-#endif /* CONFIG_TIVA_ADC_REGDEBUG */
-
-/****************************************************************************
- * Name: tiva_adc_modifyreg
- *
- * Description:
- * Atomically modify the specified bits in a memory mapped register
- *
- * Input Parameters:
- * addr - The address of the register to write to
- *
- ****************************************************************************/
-
-#ifdef CONFIG_TIVA_ADC_REGDEBUG
-static void tiva_adc_modifyreg(struct tiva_adc_s *priv, unsigned int addr,
- uint32_t clearbits, uint32_t setbits)
-{
- uint32_t regval = 0;
- irqstate_t flags = irqsave();
- regval = tiva_adc_getreg(priv, addr);
- regval &= ~clearbits;
- regval |= setbits;
- tiva_adc_putreg(priv, addr, regval);
- irqrestore(flags);
-}
-#endif /* CONFIG_TIVA_ADC_REGDEBUG */
-
-/* TM4C-specific ADC functions **********************************************/
-
-/* Peripheral (base) level **************************************************/
-
-/****************************************************************************
- * Name: adc_state
- *
- * Description:
- * Toggles the operational state of the ADC peripheral
- *
- * Input Parameters:
- * state - operation state
- *
- ****************************************************************************/
-
-static int adc_state(struct tiva_adc_s *adc, bool state)
-{
- if (state == TIVA_ADC_ENABLE)
- {
- /* Enable clocking to the ADC peripheral */
-
-#ifdef TIVA_SYSCON_RCGCADC
- modifyreg32(TIVA_SYSCON_RCGCADC, 0, 1 << adc->devno);
-#else
- modifyreg32(TIVA_SYSCON_RCGC0, 0, SYSCON_RCGC0_ADC0);
-#endif
- return OK;
- }
- else if (state == TIVA_ADC_DISABLE)
- {
- /* Disable clocking to the ADC peripheral */
-
-#ifdef TIVA_SYSCON_RCGCADC
- modifyreg32(TIVA_SYSCON_RCGCADC, 1 << adc->devno, 0);
-#else
- modifyreg32(TIVA_SYSCON_RCGC0, SYSCON_RCGC0_ADC0, 0);
-#endif
- return OK;
- }
-
- /* ERROR! */
-
- return -1;
-}
-
-/****************************************************************************
- * Name: adc_clock
- *
- * Description:
- * Sets the ADC peripherals clock to the desired frequency.
- *
- * Input Parameters:
- * freq - ADC clock value; dependent on platform:
- *
- * TM4C123 - Select either MOSC or PIOSC. Both result in 16 MHz operation,
- * however the PIOSC allows the ADC to operate in deep sleep mode.
- *
- * TM4C129 - For the 129, there is still a selection between various internal
- * clocks, however the output frequency is variable (16 MHz - 32 MHz); so it
- * is much more intuitive to allow the clock variable be a frequency value.
- *
- ****************************************************************************/
-
-static void adc_clock(uint32_t freq)
-{
-#if defined(CONFIG_ARCH_CHIP_TM4C123)
- /* For the TM4C123, the ADC clock source does not affect the frequency, it
- * runs at 16 MHz regardless. You end up selecting between the MOSC (default)
- * or the PIOSC. The PIOSC allows the ADC to operate even in deep sleep mode.
- * Since this is the case, the clock value for
- */
-
- uintptr_t ccreg = (TIVA_ADC0_BASE + TIVA_ADC_CC_OFFSET);
- modifyreg32(ccreg, 0, (freq & ADC_CC_CS_MASK));
-
-#elif defined (CONFIG_ARCH_CHIP_TM4C129)
- /* check clock bounds and specific match cases */
-
- uint32_t clk_src = 0;
- uint32_t div = 0;
- if (clock > TIVA_ADC_CLOCK_MAX)
- {
- clk_src = ADC_CC_CS_SYSPLL;
- div = (BOARD_FVCO_FREQUENCY / TIVA_ADC_CLOCK_MAX);
- }
- else if (clock < TIVA_ADC_CLOCK_MIN)
- {
- clk_src = ADC_CC_CS_PIOSC;
- div = 1;
- }
- else if (clock == XTAL_FREQUENCY)
- {
- clk_src = ADC_CC_CS_MOSC;
- div = 1;
- }
- else
- {
- clk_src = ADC_CC_CS_SYSPLL;
- div = (BOARD_FVCO_FREQUENCY / freq);
- }
-
- uintptr_t ccreg = (TIVA_ADC0_BASE + TIVA_ADC_CC_OFFSET);
- modifyreg32(ccreg, 0, CLOCK_CONFIG(div, clk_src));
-#else
-# error Unsupported architecture reported
-#endif
-}
-
-/****************************************************************************
- * Name: adc_vref
- *
- * Description:
- * Sets the ADC peripherals clock to the desired frequency.
- *
- * Input Parameters:
- * vref - ADC clock voltage reference source
- *
- ****************************************************************************/
-
-#ifdef CONFIG_ARCH_CHIP_TM4C129
-static void adc_vref(uint8_t vref)
-{
- uintptr_t ctlreg = (TIVA_ADC0_BASE + TIVA_ADC_CTL_OFFSET);
- if (vref == 0)
- {
- modifyreg32(ctlreg, vref, 0);
- }
- else
- {
- modifyreg32(ctlreg, 0, vref);
- }
-}
-#endif
-
-/****************************************************************************
- * Name: adc_sample_rate
- *
- * Description:
- * Sets the ADC sample rate as follows for each processor.
- * TM4C123 - by maximum samples: 125 ksps, 250 ksps, 500 ksps or 1 Msps
- * TM4C129 - by a divisor either being full, half, quarter or
- * an eighth.
- *
- * Input Parameters:
- * rate - ADC sample rate divisor
- *
- ****************************************************************************/
-
-static void adc_sample_rate(uint8_t rate)
-{
- uintptr_t pcreg = (TIVA_ADC0_BASE + TIVA_ADC_PC_OFFSET);
-
- /* NOTE: ADC_PC_SR_MASK is intended for use with the TM4C123, the
- * alternative is ADC_PC_MCR_MASK for the TM4C129. However both masks
- * mask off the first 4 bits (0xF) so there is no need to distinguish
- * between the two.
- */
-
- modifyreg32(pcreg, 0, (rate & ADC_PC_SR_MASK));
-}
-
-/****************************************************************************
- * Name: adc_proc_trig
- *
- * Description:
- * Triggers the sample sequence to start it's conversion(s) and store them
- * to the FIFO. This is only required when the trigger source is set to the
- * processor.
- *
- * Input parameters:
- * adc - which ADC peripherals' sample sequencers to trigger
- * sse_mask - sample sequencer bitmask, each sse is 1 shifted by the sse
- * number. e.g.
- * SSE0 = 1 << 0
- * SSE1 = 1 << 1
- * SSE2 = 1 << 2
- * SSE3 = 1 << 3
- *
- ****************************************************************************/
-
-static void adc_proc_trig(struct tiva_adc_s *adc, uint8_t sse_mask)
-{
- uintptr_t pssireg = TIVA_ADC_PSSI(adc->devno);
- tiva_adc_modifyreg(adc, pssireg, 0, sse_mask);
-#ifdef CONFIG_TIVA_ADC_SYNC
-# warning CONFIG_TIVA_ADC_SYNC unsupported at this time.
-#endif
-}
-
-/****************************************************************************
- * Name: adc_int_status
- *
- * Description:
- * Returns raw interrupt status for the input ADC
- *
- * Input parameters:
- * adc - which ADC peripherals' interrupt status to retrieve
- *
- ****************************************************************************/
-
-static uint32_t adc_int_status(struct tiva_adc_s *adc)
-{
- return tiva_adc_getreg(adc, TIVA_ADC_RIS(adc->devno));
-}
-
-/* Sample sequencer (SSE) functions *****************************************/
-
-/****************************************************************************
- * Name: sse_state
- *
- * Description:
- * Sets the operation state of an ADC's sample sequencer (SSE). SSEs must
- * be configured before being enabled.
- *
- * Input parameters:
- * adc - peripheral state
- * sse - sample sequencer
- * state - sample sequencer enable/disable state
- *
- ****************************************************************************/
-
-static void sse_state(struct tiva_adc_s *adc, uint8_t sse, bool state)
-{
- uintptr_t actssreg = TIVA_ADC_ACTSS(adc->devno);
- if (state == TIVA_ADC_ENABLE)
- {
- tiva_adc_modifyreg(adc, actssreg, 0, (1 << sse));
- }
- else
- {
- tiva_adc_modifyreg(adc, actssreg, (1 << sse), 0);
- }
-
- adc->sse[sse]->ena = state;
-}
-
-/****************************************************************************
- * Name: sse_trigger
- *
- * Description:
- * Sets the trigger configuration for an ADC's sample sequencer (SSE).
- * Possible triggers are the following:
- * - Processor
- * - PWMs, requires that one of the PWMnn_TRIG_CFG defines be OR'd
- * into the trigger value.
- * - Timers
- * - GPIO (which GPIO is platform specific, consult the datasheet)
- * - Always
- * - !!UNSUPPORTED: Comparators
- *
- * Input parameters:
- * adc - peripheral state
- * sse - sample sequencer
- * trigger - interrupt trigger
- *
- ****************************************************************************/
-
-static void sse_trigger(struct tiva_adc_s *adc, uint8_t sse, uint32_t trigger)
-{
- uintptr_t emuxreg = (TIVA_ADC_EMUX(adc->devno));
- uint32_t trig = 0;
- if ((trigger & ADC_EMUX_MASK(0)) == 0)
- {
- /* The 0 value is a special case since using modifyregn() results in an
- * ORing of the register value; we need to unset those bits if it's a 0.
- */
-
- tiva_adc_modifyreg(adc, emuxreg, (0xF << sse), 0);
- }
- else
- {
- trig = ((trigger << ADC_EMUX_SHIFT(sse)) & ADC_EMUX_MASK(sse));
- tiva_adc_modifyreg(adc, emuxreg, 0, trig);
- }
-
- /* NOTE: PWM triggering needs an additional register to be set (ADC_TSSEL)
- * A platform specific IOCTL command is provided to configure the triggering.
- */
-}
-
-/****************************************************************************
- * Name: sse_pwm_trig_ioctl
- *
- * Description:
- * Additional triggering configuration for PWM. Sets which PWM and which
- * generator.
- *
- * Input parameters:
- * adc - peripheral state
- * sse - sample sequencer
- * cfg - which PWM modulator and generator to use, use TIVA_ADC_PWM_TRIG
- * to encode the value correctly
- *
- ****************************************************************************/
-
-#ifdef CONFIG_EXPERIMENTAL
-static void sse_pwm_trig_ioctl(struct tiva_adc_s *adc, uint8_t sse, uint32_t cfg)
-{
- /* PWM triggering needs an additional register to be set (ADC_TSSEL) */
-
- uintptr_t tsselreg = TIVA_ADC_TSSEL(adc->devno);
-
- if ((cfg & ADC_EMUX_MASK(0)) == 1)
- {
- tiva_adc_modifyreg(adc, tsselreg, 0, cfg);
- }
- else
- {
- tiva_adc_modifyreg(adc, tsselreg, cfg, 0);
- }
-}
-#endif
-
-/****************************************************************************
- * Name: sse_int
- *
- * Description:
- * Sets the interrupt state of an ADC's sample sequencer (SSE). SSEs must
- * be enabled before setting interrupt state.
- *
- * Input parameters:
- * adc - peripheral state
- * sse - sample sequencer
- * state - sample sequencer enable/disable interrupt state
- *
- ****************************************************************************/
-
-static void sse_int_state(struct tiva_adc_s *adc, uint8_t sse, bool state)
-{
- uintptr_t imreg = TIVA_ADC_IM(adc->devno);
- if (adc->sse[sse])
- {
- sse_clear_int(adc, sse);
- }
- if (state == TIVA_ADC_ENABLE)
- {
- tiva_adc_modifyreg(adc, imreg, 0, (1 << sse));
- }
- else
- {
- tiva_adc_modifyreg(adc, imreg, (1 << sse), 0);
- }
-}
-
-/****************************************************************************
- * Name: sse_int_status
- *
- * Description:
- * Returns interrupt status for the specificed SSE
- *
- * Input parameters:
- * adc - which ADC peripherals' interrupt status to retrieve
- * sse - which SSE interrupt status to retrieve
- *
- ****************************************************************************/
-
-static bool sse_int_status(struct tiva_adc_s *adc, uint8_t sse)
-{
- return (adc_int_status(adc) & (1 << sse)) > 0 ? true : false;
-}
-
-/****************************************************************************
- * Name: sse_clear_int
- *
- * Description:
- * Clears the interrupt bit for the SSE.
- *
- * Input parameters:
- * adc - peripheral state
- * sse - sample sequencer
- * state - sample sequencer
- *
- ****************************************************************************/
-
-static void sse_clear_int(struct tiva_adc_s *adc, uint8_t sse)
-{
- uintptr_t iscreg = TIVA_ADC_ISC(adc->devno);
- tiva_adc_modifyreg(adc, iscreg, 0, (1 << sse));
-}
-
-/****************************************************************************
- * Name: sse_data
- *
- * Description:
- * Retrieves data from the FIFOs for all steps in the given sample sequencer.
- * The input data buffer MUST be as large or larger than the sample sequencer.
- * otherwise
- *
- * Input parameters:
- * adc - peripheral state
- * sse - sample sequencer
- *
- * Return value:
- * number of steps read from FIFO.
- *
- ****************************************************************************/
-
-static int sse_data(struct tiva_adc_s *adc, uint8_t sse)
-{
- uint32_t ssfstatreg =
- tiva_adc_getreg(adc, TIVA_ADC_BASE(adc->devno) + TIVA_ADC_SSFSTAT(sse));
- int32_t data = 0;
- uint8_t fifo_count = 0;
-
- /* Read samples from the FIFO until it is empty */
-
- while (!(ssfstatreg & ADC_SSFSTAT_EMPTY) && fifo_count < SSE_MAX_STEP)
- {
- /* Read the FIFO and copy it to the destination */
-
- data =
- tiva_adc_getreg(adc, TIVA_ADC_BASE(adc->devno) + TIVA_ADC_SSFIFO(sse));
- (void)adc_receive(adc->dev, GET_AIN(adc->devno, sse, fifo_count), data);
- fifo_count++;
-
- /* refresh fifo status register state */
-
- ssfstatreg =
- tiva_adc_getreg(adc, TIVA_ADC_BASE(adc->devno) + TIVA_ADC_SSFSTAT(sse));
- }
-
- return fifo_count;
-}
-
-/****************************************************************************
- * Name: sse_priority
- *
- * Description:
- * Sets the priority configuration for an ADC's sample sequencer (SSE). The
- * priority value ranges from 0 to 3, 0 being the highest priority, 3 being
- * the lowest. There can be no duplicate values.
- *
- * Input parameters:
- * adc - peripheral state
- * sse - sample sequencer
- * priority - conversion priority
- *
- ****************************************************************************/
-
-static void sse_priority(struct tiva_adc_s *adc, uint8_t sse, uint8_t priority)
-{
- uintptr_t ssprireg = TIVA_ADC_SSPRI(adc->devno);
- uint32_t sspri = 0;
-
- if (priority == 0)
- {
- /* The 0 value is a special case since using modifyregn() results in an
- * ORing of the register value; we need to unset those bits if it's a 0.
- */
-
- sspri = (ADC_SSPRI_MASK(sse) & (0x3 << ADC_SSPRI_SHIFT(sse)));
- tiva_adc_modifyreg(adc, ssprireg, sspri, 0);
- }
- else
- {
- sspri = (ADC_SSPRI_MASK(sse) & (priority << ADC_SSPRI_SHIFT(sse)));
- tiva_adc_modifyreg(adc, ssprireg, 0, sspri);
- }
-}
-
-/****************************************************************************
- * Name: sse_register_chn
- *
- * Description:
- * Registers an input channel to an SSE. Channels are registered according
- * to the step and channel values stored in the channel struct. If the SSE
- * already has a channel registered, it is overwritten by the new channel.
- *
- * *SSEMUX only supported on TM4C129 devices
- *
- * Input parameters:
- * adc - peripheral state
- * sse - sample sequencer
- * chn - sample sequencer step
- * ain - analog input pin
- *
- ****************************************************************************/
-
-static void sse_register_chn(struct tiva_adc_s *adc, uint8_t sse, uint8_t chn,
- uint32_t ain)
-{
- /* Configure SSE mux (SSMUX) with step number */
-
- uintptr_t ssmuxreg = (TIVA_ADC_BASE(adc->devno) + TIVA_ADC_SSMUX(sse));
- uint32_t step = 0;
-
- if (ain > 0)
- {
- step = ((ain << ADC_SSMUX_MUX_SHIFT(chn)) & ADC_SSMUX_MUX_MASK(chn));
- tiva_adc_modifyreg(adc, ssmuxreg, 0, step);
- }
- else
- {
- step = ((0xF << ADC_SSMUX_MUX_SHIFT(chn)) & ADC_SSMUX_MUX_MASK(chn));
- tiva_adc_modifyreg(adc, ssmuxreg, step, 0);
- }
-
-#ifdef CONFIG_ARCH_CHIP_TM4C129
- /* Configure SSE extended mux (SSEMUX) with step number and configuration */
-
- ssmuxreg = (TIVA_ADC_BASE(adc->devno) + TIVA_ADC_SSMUX(sse));
- step = ((1 << ADC_SSEMUX_MUX_SHIFT(chn)) & ADC_SSEMUX_MUX_MASK(chn));
- if (chn > MAX_NORMAL_CHN)
- {
- tiva_adc_modifyreg(adc, ssmuxreg, 0, step);
- }
- else
- {
- tiva_adc_modifyreg(adc, ssmuxreg, step, 0);
- }
-#endif
-}
-
-/****************************************************************************
- * Name: sse_differential
- *
- * Description:
- * Sets the differential capability for a SSE. !! UNSUPPORTED
- *
- * Input parameters:
- * adc - peripheral state
- * sse - sample sequencer
- * chn - sample sequencer channel
- * diff - differential configuration
- *
- ****************************************************************************/
-
-static void sse_differential(struct tiva_adc_s *adc, uint8_t sse, uint8_t chn,
- uint32_t diff)
-{
-#ifdef CONFIG_TIVA_ADC_DIFFERENTIAL
-# error CONFIG_TIVA_ADC_DIFFERENTIAL unsupported!!
-#else
-
- /* for now, ensure the FIFO is used and differential sampling is disabled */
-
- uintptr_t ssopreg = (TIVA_ADC_BASE(adc->devno) + TIVA_ADC_SSOP(sse));
- uint32_t sdcopcfg = (1 << chn);
- tiva_adc_modifyreg(adc, ssopreg, sdcopcfg, 0);
-#endif
-}
-
-/****************************************************************************
- * Name: sse_sample_hold_time
- *
- * Description:
- * Set the sample and hold time for this step.
- *
- * This is not available on all devices, however on devices that do not
- * support this feature these reserved bits are ignored on write access.
- *
- * Input parameters:
- * adc - peripheral state
- * sse - sample sequencer
- * chn - sample sequencer channel
- * shold - sample and hold time
- *
- ****************************************************************************/
-
-#ifdef CONFIG_EXPERIMENTAL
-static void sse_sample_hold_time(struct tiva_adc_s *adc, uint8_t sse,
- uint8_t chn, uint32_t shold)
-{
- uintptr_t sstshreg = (TIVA_ADC_BASE(adc->devno) + TIVA_ADC_SSTSH(sse));
- if (shold > 0)
- {
- tiva_adc_modifyreg(adc, sstshreg, 0, (shold << ADC_SSTSH_SHIFT(sse)));
- }
- else
- {
- tiva_adc_modifyreg(adc, sstshreg, ADC_SSTSH_MASK(sse), 0);
- }
-}
-#endif
-
-/****************************************************************************
- * Name: sse_step_cfg
- *
- * Description:
- * Configures the given SSE step to one of the following options:
- * -Temperature sensor select: this step is muxed to the internal
- * temperature sensor.
- * -Interrupt enabled select: this step causes the interrupt bit to
- * be set and, if the MASK0 bit in ADC_IM register is set, the
- * interrupt is promoted to the interrupt controller.
- * -Sequence end select: This step is the last sequence to be sampled.
- * This MUST be set somewhere in the SSE.
- * -*Comparator/Differential select: The analog input is differentially
- * sampled. The corresponding ADCSSMUXn nibble must be set to the pair
- * number "i", where the paired inputs are "2i and 2i+1". Because the
- * temperature sensor does not have a differential option, this bit must
- * not be set when the TS3 bit is set.
- *
- * *Comparator/Differential functionality is unsupported and ignored.
- *
- * Input parameters:
- * adc - peripheral state
- * sse - sample sequencer
- * chn - sample sequencer channel
- * cfg - step configuration
- *
- ****************************************************************************/
-
-static void sse_step_cfg(struct tiva_adc_s *adc, uint8_t sse, uint8_t chn,
- uint8_t cfg)
-{
- uintptr_t ssctlreg = (TIVA_ADC_BASE(adc->devno) + TIVA_ADC_SSCTL(sse));
- uint32_t ctlcfg = cfg << ADC_SSCTL_SHIFT(chn);
- tiva_adc_modifyreg(adc, ssctlreg, 0, ctlcfg);
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: tiva_adc_initialize
- *
- * Description:
- * Initialize the ADC
- *
- * Returned Value:
- * Valid can device structure reference on success; a NULL on failure
- *
- ****************************************************************************/
-
-struct adc_dev_s *tiva_adc_initialize(int adc_num)
-{
- avdbg("tiva_adc_initialize\n");
-
- /* Initialize the private ADC device data structure */
-
- struct tiva_adc_s *adc;
- uint8_t s;
-#ifdef CONFIG_TIVA_ADC0
- if (adc_num == 0)
- {
- adc0.ena = false;
- adc0.devno = 0;
-
- /* Debug stuff */
-
-# ifdef CONFIG_TIVA_ADC_REGDEBUG
- adc0.wrlast = false;
- adc0.addrlast = 0x0;
- adc0.vallast = 0x0;
- adc0.ntimes = 0;
-# endif /* CONFIG_TIVA_ADC_REGDEBUG */
-
- /* Initialize SSEs */
-
-# ifdef CONFIG_TIVA_ADC0_SSE0
- sse00.ena = false;
- sse00.irq = TIVA_IRQ_ADC0;
- sse00.num = 0;
-# ifdef TIVA_ADC_HAVE_INTERRUPTS
- sem_init(&sse00.exclsem, SEM_PROCESS_PRIVATE, 1);
-# endif
- adc0.sse[0] = &sse00;
-# endif /* CONFIG_TIVA_ADC0_SSE0 */
-
-# ifdef CONFIG_TIVA_ADC0_SSE1
- sse01.ena = false;
- sse01.irq = TIVA_IRQ_ADC1;
- sse01.num = 1;
-# ifdef TIVA_ADC_HAVE_INTERRUPTS
- sem_init(&sse01.exclsem, SEM_PROCESS_PRIVATE, 1);
-# endif
- adc0.sse[1] = &sse01;
-# endif /* CONFIG_TIVA_ADC0_SSE1 */
-
-# ifdef CONFIG_TIVA_ADC0_SSE2
- sse02.ena = false;
- sse02.irq = TIVA_IRQ_ADC2;
- sse02.num = 2;
-# ifdef TIVA_ADC_HAVE_INTERRUPTS
- sem_init(&sse02.exclsem, SEM_PROCESS_PRIVATE, 1);
-# endif
- adc0.sse[2] = &sse02;
-# endif /* CONFIG_TIVA_ADC0_SSE2 */
-
-# ifdef CONFIG_TIVA_ADC0_SSE3
- sse03.ena = false;
- sse03.irq = TIVA_IRQ_ADC3;
- sse03.num = 3;
-# ifdef TIVA_ADC_HAVE_INTERRUPTS
- sem_init(&sse03.exclsem, SEM_PROCESS_PRIVATE, 1);
-# endif
- adc0.sse[3] = &sse03;
-# endif /* CONFIG_TIVA_ADC0_SSE3 */
-
- adc0.dev = &g_adcdev0;
- adc = &adc0;
-
- /* Initialize the public ADC device data structure */
-
- g_adcdev0.ad_ops = &g_adcops;
- g_adcdev0.ad_priv = &adc0;
- }
-#endif /* CONFIG_TIVA_ADC0 */
-
-#ifdef CONFIG_TIVA_ADC1
- if (adc_num == 1)
- {
- adc1.ena = false;
- adc1.devno = 0;
-
- /* Debug stuff */
-
-# ifdef CONFIG_TIVA_ADC_REGDEBUG
- adc1.wrlast = false;
- adc1.addrlast = 0x0;
- adc1.vallast = 0x0;
- adc1.ntimes = 0;
-# endif /* CONFIG_TIVA_ADC_REGDEBUG */
-
- /* Initialize SSEs */
-
-# ifdef CONFIG_TIVA_ADC1_SSE0
- sse10.ena = false;
- sse10.irq = TIVA_IRQ_ADC1_0;
- sse10.num = 0;
-# ifdef TIVA_ADC_HAVE_INTERRUPTS
- sem_init(&sse10.exclsem, SEM_PROCESS_PRIVATE, 1);
-# endif
- adc1.sse[0] = &sse10;
-# endif /* CONFIG_TIVA_ADC1_SSE0 */
-
-# ifdef CONFIG_TIVA_ADC1_SSE1
- sse11.ena = false;
- sse11.irq = TIVA_IRQ_ADC1_1;
- sse11.num = 1;
-# ifdef TIVA_ADC_HAVE_INTERRUPTS
- sem_init(&sse11.exclsem, SEM_PROCESS_PRIVATE, 1);
-# endif
-
- adc1.sse[1] = &sse11;
-# endif /* CONFIG_TIVA_ADC1_SSE1 */
-
-# ifdef CONFIG_TIVA_ADC1_SSE2
- sse12.ena = false;
- sse12.irq = TIVA_IRQ_ADC1_2;
- sse12.num = 2;
-# ifdef TIVA_ADC_HAVE_INTERRUPTS
- sem_init(&sse12.exclsem, SEM_PROCESS_PRIVATE, 1);
-# endif
- adc1.sse[2] = &sse12;
-# endif /* CONFIG_TIVA_ADC1_SSE2 */
-
-# ifdef CONFIG_TIVA_ADC1_SSE3
- sse13.ena = false;
- sse13.irq = TIVA_IRQ_ADC1_3;
- sse13.num = 3;
-# ifdef TIVA_ADC_HAVE_INTERRUPTS
- sem_init(&sse13.exclsem, SEM_PROCESS_PRIVATE, 1);
-# endif
- adc1.sse[3] = &sse13;
-# endif /* CONFIG_TIVA_ADC1_SSE3 */
-
- adc1.dev = &g_adcdev1;
- adc = &adc1;
-
- /* Initialize the public ADC device data structure */
-
- g_adcdev1.ad_ops = &g_adcops;
- g_adcdev1.ad_priv = &adc1;
- }
-#endif /* CONFIG_TIVA_ADC1 */
-
- if (adc_num > 1)
- {
- adbg("ERROR: Invalid ADV devno given, must be 0 or 1! ADC Devno: %d\n",
- adc_num);
- return NULL;
- }
-
- /* Have the common peripheral properties already been initialized? If yes,
- * continue.
- */
-
- if (adc_common.init[adc->devno] == false)
- {
- /* turn on peripheral */
-
- if (adc_state(adc, TIVA_ADC_ENABLE) < 0)
- {
- adbg("ERROR: failure to power ADC peripheral (devno=%d)\n",
- adc_num);
- return NULL;
- }
-
- /* set clock */
-
- adc_clock(CONFIG_TIVA_ADC_CLOCK);
-
- /* set sampling rate */
-
- adc_sample_rate(TIVA_ADC_SAMPLE_RATE_FASTEST);
-
-#ifdef CONFIG_ARCH_CHIP_TM4C129
- /* voltage reference */
-
- adc_vref();
-#endif /* CONFIG_ARCH_CHIP_TM4C129 */
- adc_common.init[adc->devno] = true;
- }
-
- /* Initialize peripheral */
-
- /* Have we already been initialized? If yes, than just hand out the interface
- * one more time.
- */
-
- if (adc->ena == false)
- {
-#if CONFIG_TIVA_ADC0
- if (adc_num == 0)
- {
- /* Configure sample sequencers */
-
- tiva_adc0_sse_init();
-
- /* Configure channels & register interrupts */
-
-# if TIVA_ADC_HAVE_INTERRUPTS
- tiva_adc0_assign_interrupts();
-# endif
- tiva_adc0_assign_channels();
- }
-#endif
-
-#if CONFIG_TIVA_ADC1
- if (adc_num == 1)
- {
- /* Configure sample sequencers */
-
- tiva_adc1_sse_init();
-
- /* Configure channels & register interrupts */
-
-# if TIVA_ADC_HAVE_INTERRUPTS
- tiva_adc1_assign_interrupts();
-# endif
- tiva_adc1_assign_channels();
- }
-#endif
-
- /* Enable SSEs */
-
- for (s = 0; s < SSE_PER_BASE; ++s)
- {
- if (adc_common.sse[SSE_IDX(adc_num, s)])
- {
- sse_state(adc, s, TIVA_ADC_ENABLE);
- sse_clear_int(adc, s);
- }
- }
-
- /* Now we are initialized */
-
- adc->ena = true;
- }
-
- /* Return a pointer to the device structure */
-
- avdbg("Returning %x\n", adc->dev);
- return adc->dev;
-}
-
-/****************************************************************************
- * Name: tiva_adc_lock
- *
- * Description:
- * Get exclusive access to the ADC interface
- *
- ****************************************************************************/
-
-void tiva_adc_lock(FAR struct tiva_adc_s *priv, int sse)
-{
-#if TIVA_ADC_HAVE_INTERRUPTS
- int ret;
-
- avdbg("Locking\n");
-
- do
- {
- ret = sem_wait(&priv->sse[sse]->exclsem);
-
- /* This should only fail if the wait was canceled by an signal (and the
- * worker thread will receive a lot of signals).
- */
-
- DEBUGASSERT(ret == OK || errno == EINTR);
- }
- while (ret < 0);
-#endif
-}
-
-/****************************************************************************
- * Name: tiva_adc_unlock
- *
- * Description:
- * Relinquish the lock on the ADC interface
- *
- ****************************************************************************/
-
-void tiva_adc_unlock(FAR struct tiva_adc_s *priv, int sse)
-{
-#if TIVA_ADC_HAVE_INTERRUPTS
- avdbg("Unlocking\n");
- sem_post(&priv->sse[sse]->exclsem);
-#endif
-}
-
-/****************************************************************************
- * Name: tiva_adc_getreg
- *
- * Description:
- * Read any 32-bit register using an absolute address.
- *
- ****************************************************************************/
-
-#ifdef CONFIG_TIVA_ADC_REGDEBUG
-uint32_t tiva_adc_getreg(struct tiva_adc_s *priv, uintptr_t address)
-{
- uint32_t regval = getreg32(address);
-
- if (tiva_adc_checkreg(priv, false, regval, address))
- {
- lldbg("%08x->%08x\n", address, regval);
- }
-
- return regval;
-}
-
-/****************************************************************************
- * Name: tiva_adc_putreg
- *
- * Description:
- * Write to any 32-bit register using an absolute address.
- *
- ****************************************************************************/
-
-void tiva_adc_putreg(struct tiva_adc_s *priv, uintptr_t address,
- uint32_t regval)
-{
- if (tiva_adc_checkreg(priv, true, regval, address))
- {
- lldbg("%08x<-%08x\n", address, regval);
- }
-
- putreg32(regval, address);
-}
-#endif /* CONFIG_TIVA_ADC_REGDEBUG */
-
-/****************************************************************************
- * Name: Verbose, generated code
- *
- * Description:
- * Generated with a python script, the following code is used to deal with
- * the defines generated from the Kconfig menu. Read at your own risk.
- *
- ****************************************************************************/
-
-/* Sample sequencer initialization ******************************************/
-
-#ifdef CONFIG_TIVA_ADC0
-static void tiva_adc0_sse_init(void)
-{
-# ifdef CONFIG_TIVA_ADC0_SSE0
- sse_state(&adc0, 0, TIVA_ADC_DISABLE);
- sse_priority(&adc0, 0, CONFIG_TIVA_ADC0_SSE0_PRIORITY);
- sse_trigger(&adc0, 0, CONFIG_TIVA_ADC0_SSE0_TRIGGER);
- adc_common.sse[SSE_IDX(0, 0)] = true;
-# endif
-# ifdef CONFIG_TIVA_ADC0_SSE1
- sse_state(&adc0, 1, TIVA_ADC_DISABLE);
- sse_priority(&adc0, 1, CONFIG_TIVA_ADC0_SSE1_PRIORITY);
- sse_trigger(&adc0, 1, CONFIG_TIVA_ADC0_SSE1_TRIGGER);
- adc_common.sse[SSE_IDX(0, 1)] = true;
-# endif
-# ifdef CONFIG_TIVA_ADC0_SSE2
- sse_state(&adc0, 2, TIVA_ADC_DISABLE);
- sse_priority(&adc0, 2, CONFIG_TIVA_ADC0_SSE2_PRIORITY);
- sse_trigger(&adc0, 2, CONFIG_TIVA_ADC0_SSE2_TRIGGER);
- adc_common.sse[SSE_IDX(0, 2)] = true;
-# endif
-# ifdef CONFIG_TIVA_ADC0_SSE3
- sse_state(&adc0, 3, TIVA_ADC_DISABLE);
- sse_priority(&adc0, 3, CONFIG_TIVA_ADC0_SSE3_PRIORITY);
- sse_trigger(&adc0, 3, CONFIG_TIVA_ADC0_SSE3_TRIGGER);
- adc_common.sse[SSE_IDX(0, 3)] = true;
-# endif
-}
-#endif /* CONFIG_TIVA_ADC0 */
-
-#ifdef CONFIG_TIVA_ADC1
-static void tiva_adc1_sse_init(void)
-{
-# ifdef CONFIG_TIVA_ADC1_SSE0
- sse_state(&adc1, 0, TIVA_ADC_DISABLE);
- sse_priority(&adc1, 0, CONFIG_TIVA_ADC1_SSE0_PRIORITY);
- sse_trigger(&adc1, 0, CONFIG_TIVA_ADC1_SSE0_TRIGGER);
- adc_common.sse[SSE_IDX(1, 0)] = true;
-# endif
-# ifdef CONFIG_TIVA_ADC1_SSE1
- sse_state(&adc1, 1, TIVA_ADC_DISABLE);
- sse_priority(&adc1, 1, CONFIG_TIVA_ADC1_SSE1_PRIORITY);
- sse_trigger(&adc1, 1, CONFIG_TIVA_ADC1_SSE1_TRIGGER);
- adc_common.sse[SSE_IDX(1, 1)] = true;
-# endif
-# ifdef CONFIG_TIVA_ADC1_SSE2
- sse_state(&adc1, 2, TIVA_ADC_DISABLE);
- sse_priority(&adc1, 2, CONFIG_TIVA_ADC1_SSE2_PRIORITY);
- sse_trigger(&adc1, 2, CONFIG_TIVA_ADC1_SSE2_TRIGGER);
- adc_common.sse[SSE_IDX(1, 2)] = true;
-# endif
-# ifdef CONFIG_TIVA_ADC1_SSE3
- sse_state(&adc1, 3, TIVA_ADC_DISABLE);
- sse_priority(&adc1, 3, CONFIG_TIVA_ADC1_SSE3_PRIORITY);
- sse_trigger(&adc1, 3, CONFIG_TIVA_ADC1_SSE3_TRIGGER);
- adc_common.sse[SSE_IDX(1, 3)] = true;
-# endif
-}
-#endif /* CONFIG_TIVA_ADC1 */
-
-/* Sample sequencer interrupt initialization ********************************/
-
-#ifdef TIVA_ADC_HAVE_INTERRUPTS
-static void tiva_adc0_assign_interrupts(void)
-{
-# ifdef CONFIG_TIVA_ADC0
- uint32_t ret = 0;
-# ifdef CONFIG_TIVA_ADC0_SSE0
- ret = irq_attach(sse00.irq, (xcpt_t)adc0_sse0_interrupt);
- if (ret < 0)
- {
- adbg("ERROR: Failed to attach IRQ %d: %d\n", sse00.irq, ret);
- return;
- }
- up_enable_irq(sse00.irq);
-# endif
-# ifdef CONFIG_TIVA_ADC0_SSE1
- ret = irq_attach(sse01.irq, (xcpt_t)adc0_sse1_interrupt);
- if (ret < 0)
- {
- adbg("ERROR: Failed to attach IRQ %d: %d\n", sse01.irq, ret);
- return;
- }
- up_enable_irq(sse01.irq);
-# endif
-# ifdef CONFIG_TIVA_ADC0_SSE2
- ret = irq_attach(sse02.irq, (xcpt_t)adc0_sse2_interrupt);
- if (ret < 0)
- {
- adbg("ERROR: Failed to attach IRQ %d: %d\n", sse02.irq, ret);
- return;
- }
- up_enable_irq(sse02.irq);
-# endif
-# ifdef CONFIG_TIVA_ADC0_SSE3
- ret = irq_attach(sse03.irq, (xcpt_t)adc0_sse3_interrupt);
- if (ret < 0)
- {
- adbg("ERROR: Failed to attach IRQ %d: %d\n", sse03.irq, ret);
- return;
- }
- up_enable_irq(sse03.irq);
-# endif
-# endif
-};
-
-static void tiva_adc1_assign_interrupts(void)
-{
-# ifdef CONFIG_TIVA_ADC1
- uint32_t ret = 0;
-# ifdef CONFIG_TIVA_ADC1_SSE0
- ret = irq_attach(sse10.irq, (xcpt_t)adc1_sse0_interrupt);
- if (ret < 0)
- {
- adbg("ERROR: Failed to attach IRQ %d: %d\n", sse10.irq, ret);
- return;
- }
- up_enable_irq(sse10.irq);
-# endif
-# ifdef CONFIG_TIVA_ADC1_SSE1
- ret = irq_attach(sse11.irq, (xcpt_t)adc1_sse1_interrupt);
- if (ret < 0)
- {
- adbg("ERROR: Failed to attach IRQ %d: %d\n", sse11.irq, ret);
- return;
- }
- up_enable_irq(sse11.irq);
-# endif
-# ifdef CONFIG_TIVA_ADC1_SSE2
- ret = irq_attach(sse12.irq, (xcpt_t)adc1_sse2_interrupt);
- if (ret < 0)
- {
- adbg("ERROR: Failed to attach IRQ %d: %d\n", sse12.irq, ret);
- return;
- }
- up_enable_irq(sse12.irq);
-# endif
-# ifdef CONFIG_TIVA_ADC1_SSE3
- ret = irq_attach(sse13.irq, (xcpt_t)adc1_sse3_interrupt);
- if (ret < 0)
- {
- adbg("ERROR: Failed to attach IRQ %d: %d\n", sse13.irq, ret);
- return;
- }
- up_enable_irq(sse13.irq);
-# endif
-# endif
-};
-#endif /* TIVA_ADC_HAVE_INTERRUPTS */
-
-/* Sample sequencer interrupt declaration ********************************/
-
-#ifdef TIVA_ADC_HAVE_INTERRUPTS
-# ifdef CONFIG_TIVA_ADC0
-# ifdef CONFIG_TIVA_ADC0_SSE0
-static void adc0_sse0_interrupt(int irq, void *context)
-{
- int ret;
-
- DEBUGASSERT((sse00.ena == true) &&
- (adc_common.sse[SSE_IDX(0, 0)] == true));
-
- /* disable further interrupts. Interrupts will be re-enabled
- * after the worker thread executes.
- */
-
- sse_int_state(&adc0, 0, TIVA_ADC_DISABLE);
-
- /* Clear interrupt status */
-
- sse_clear_int(&adc0, 0);
-
- /* Transfer processing to the worker thread. Since interrupts are
- * disabled while the work is pending, no special action should be
- * required to protected the work queue.
- */
-
- DEBUGASSERT(sse00.work.worker == NULL);
- ret = work_queue(HPWORK, &sse00.work, tiva_adc_read, &sse00, 0);
- if (ret != 0)
- {
- adbg("ERROR: Failed to queue work: %d\n", ret);
- }
-}
-# endif
-# ifdef CONFIG_TIVA_ADC0_SSE1
-static void adc0_sse1_interrupt(int irq, void *context)
-{
- int ret;
-
- DEBUGASSERT((sse01.ena == true) &&
- (adc_common.sse[SSE_IDX(0, 1)] == true));
-
- sse_int_state(&adc0, 1, TIVA_ADC_DISABLE);
- sse_clear_int(&adc0, 1);
- DEBUGASSERT(sse01.work.worker == NULL);
- ret = work_queue(HPWORK, &sse01.work, tiva_adc_read, &sse01, 0);
- if (ret != 0)
- {
- adbg("ERROR: Failed to queue work: %d ADC.SSE: %d.%d\n",
- ret, adc0.devno, sse01.num);
- }
-}
-# endif
-# ifdef CONFIG_TIVA_ADC0_SSE2
-static void adc0_sse2_interrupt(int irq, void *context)
-{
- int ret;
-
- DEBUGASSERT((sse02.ena == true) &&
- (adc_common.sse[SSE_IDX(0, 2)] == true));
-
- sse_int_state(&adc0, 2, TIVA_ADC_DISABLE);
- sse_clear_int(&adc0, 2);
- DEBUGASSERT(sse02.work.worker == NULL);
- ret = work_queue(HPWORK, &sse02.work, tiva_adc_read, &sse02, 0);
- if (ret != 0)
- {
- adbg("ERROR: Failed to queue work: %d ADC.SSE: %d.%d\n",
- ret, adc0.devno, sse02.num);
- }
-}
-# endif
-# ifdef CONFIG_TIVA_ADC0_SSE3
-static void adc0_sse3_interrupt(int irq, void *context)
-{
- int ret;
-
- DEBUGASSERT((sse03.ena == true) &&
- (adc_common.sse[SSE_IDX(0, 3)] == true));
-
- sse_int_state(&adc0, 3, TIVA_ADC_DISABLE);
- sse_clear_int(&adc0, 3);
- DEBUGASSERT(sse03.work.worker == NULL);
- ret = work_queue(HPWORK, &sse03.work, tiva_adc_read, &sse03, 0);
- if (ret != 0)
- {
- adbg("ERROR: Failed to queue work: %d ADC.SSE: %d.%d\n",
- ret, adc0.devno, sse03.num);
- }
-}
-# endif
-# endif /* CONFIG_TIVA_ADC0 */
-
-# ifdef CONFIG_TIVA_ADC1
-# ifdef CONFIG_TIVA_ADC1_SSE0
-static void adc1_sse0_interrupt(int irq, void *context)
-{
- int ret;
-
- DEBUGASSERT((sse10.ena == true) &&
- (adc_common.sse[SSE_IDX(1, 0)] == true));
-
- sse_int_state(&adc1, 0, TIVA_ADC_DISABLE);
- sse_clear_int(&adc1, 0);
- DEBUGASSERT(sse10.work.worker == NULL);
- ret = work_queue(HPWORK, &sse10.work, tiva_adc_read, &sse10, 0);
- if (ret != 0)
- {
- adbg("ERROR: Failed to queue work: %d ADC.SSE: %d.%d\n",
- ret, adc1.devno, sse10.num);
- }
-}
-# endif
-# ifdef CONFIG_TIVA_ADC1_SSE1
-static void adc1_sse1_interrupt(int irq, void *context)
-{
- int ret;
-
- DEBUGASSERT((sse11.ena == true) &&
- (adc_common.sse[SSE_IDX(1, 1)] == true));
-
- sse_int_state(&adc1, 1, TIVA_ADC_DISABLE);
- sse_clear_int(&adc1, 1);
- DEBUGASSERT(sse11.work.worker == NULL);
- ret = work_queue(HPWORK, &sse11.work, tiva_adc_read, &sse11, 0);
- if (ret != 0)
- {
- adbg("ERROR: Failed to queue work: %d ADC.SSE: %d.%d\n",
- ret, adc1.devno, sse11.num);
- }
-}
-# endif
-# ifdef CONFIG_TIVA_ADC1_SSE2
-static void adc1_sse2_interrupt(int irq, void *context)
-{
- int ret;
-
- DEBUGASSERT((sse12.ena == true) &&
- (adc_common.sse[SSE_IDX(1, 2)] == true));
-
- sse_int_state(&adc1, 2, TIVA_ADC_DISABLE);
- sse_clear_int(&adc1, 2);
- DEBUGASSERT(sse12.work.worker == NULL);
- ret = work_queue(HPWORK, &sse12.work, tiva_adc_read, &sse12, 0);
- if (ret != 0)
- {
- adbg("ERROR: Failed to queue work: %d ADC.SSE: %d.%d\n",
- ret, adc1.devno, sse12.num);
- }
-}
-# endif
-# ifdef CONFIG_TIVA_ADC1_SSE3
-static void adc1_sse3_interrupt(int irq, void *context)
-{
- int ret;
-
- DEBUGASSERT((sse13.ena == true) &&
- (adc_common.sse[SSE_IDX(1, 3)] == true));
-
- sse_int_state(&adc1, 3, TIVA_ADC_DISABLE);
- sse_clear_int(&adc1, 3);
- DEBUGASSERT(sse13.work.worker == NULL);
- ret = work_queue(HPWORK, &sse13.work, tiva_adc_read, &sse13, 0);
- if (ret != 0)
- {
- adbg("ERROR: Failed to queue work: %d ADC.SSE: %d.%d\n",
- ret, adc1.devno, sse13.num);
- }
-}
-# endif
-# endif /* CONFIG_TIVA_ADC1 */
-#endif /* TIVA_ADC_HAVE_INTERRUPTS */
-
-/* Channel assignment *******************************************************/
-
-#ifdef CONFIG_TIVA_ADC0
-static void tiva_adc0_assign_channels(void)
-{
-# ifdef CONFIG_TIVA_ADC0_SSE0
- adc0_sse0_chn_cfg();
-# endif
-# ifdef CONFIG_TIVA_ADC0_SSE1
- adc0_sse1_chn_cfg();
-# endif
-# ifdef CONFIG_TIVA_ADC0_SSE2
- adc0_sse2_chn_cfg();
-# endif
-# ifdef CONFIG_TIVA_ADC0_SSE3
- adc0_sse3_chn_cfg();
-# endif
-}
-#endif
-
-#ifdef CONFIG_TIVA_ADC1
-static void tiva_adc1_assign_channels(void)
-{
-# ifdef CONFIG_TIVA_ADC1_SSE0
- adc1_sse0_chn_cfg();
-# endif
-# ifdef CONFIG_TIVA_ADC1_SSE1
- adc1_sse1_chn_cfg();
-# endif
-# ifdef CONFIG_TIVA_ADC1_SSE2
- adc1_sse2_chn_cfg();
-# endif
-# ifdef CONFIG_TIVA_ADC1_SSE3
- adc1_sse3_chn_cfg();
-# endif
-}
-#endif
-
-/* Channel config ***********************************************************/
-
-#ifdef CONFIG_TIVA_ADC0
-# ifdef CONFIG_TIVA_ADC0_SSE0
-static void adc0_sse0_chn_cfg(void)
-{
- uint32_t chncfg = 0;
-# ifdef CONFIG_TIVA_ADC0_SSE0_STEP0
-# ifdef CONFIG_TIVA_ADC0_SSE0_STEP0_TS
- chncfg = ADC_SSCTL_IE | ADC_SSCTL_TS;
-# else
- chncfg = ADC_SSCTL_IE;
-# endif
- tiva_configgpio(TIVA_ADC_PIN(CONFIG_TIVA_ADC0_SSE0_STEP0_AIN));
- sse_register_chn(&adc0, 0, 0, CONFIG_TIVA_ADC0_SSE0_STEP0_AIN);
- sse_differential(&adc0, 0, 0, 0);
-# if defined (CONFIG_ARCH_CHIP_TM4C129) && (CONFIG_TIVA_ADC0_SSE0_TRIGGER == ADC_EMUX_PROC)
- sse_sample_hold_time(&adc0, 0, 0, ADC_SSTH_SHOLD_16);
-# endif
-# ifndef CONFIG_TIVA_ADC0_SSE0_STEP1
- sse_step_cfg(&adc0, 0, 0, chncfg | ADC_SSCTL_END);
-# else
- sse_step_cfg(&adc0, 0, 0, chncfg);
-# endif
-# ifdef CONFIG_TIVA_ADC0_SSE0_STEP1
-# ifdef CONFIG_TIVA_ADC0_SSE0_STEP1_TS
- chncfg = ADC_SSCTL_IE | ADC_SSCTL_TS;
-# else
- chncfg = ADC_SSCTL_IE;
-# endif
- tiva_configgpio(TIVA_ADC_PIN(CONFIG_TIVA_ADC0_SSE0_STEP1_AIN));
- sse_register_chn(&adc0, 0, 1, CONFIG_TIVA_ADC0_SSE0_STEP1_AIN);
- sse_differential(&adc0, 0, 1, 0);
-# if defined (CONFIG_ARCH_CHIP_TM4C129) && (CONFIG_TIVA_ADC0_SSE0_TRIGGER == ADC_EMUX_PROC)
- sse_sample_hold_time(&adc0, 0, 1, ADC_SSTH_SHOLD_16);
-# endif
-# ifndef CONFIG_TIVA_ADC0_SSE0_STEP2
- sse_step_cfg(&adc0, 0, 1, chncfg | ADC_SSCTL_END);
-# else
- sse_step_cfg(&adc0, 0, 1, chncfg);
-# endif
-# ifdef CONFIG_TIVA_ADC0_SSE0_STEP2
-# ifdef CONFIG_TIVA_ADC0_SSE0_STEP2_TS
- chncfg = ADC_SSCTL_IE | ADC_SSCTL_TS;
-# else
- chncfg = ADC_SSCTL_IE;
-# endif
- tiva_configgpio(TIVA_ADC_PIN(CONFIG_TIVA_ADC0_SSE0_STEP2_AIN));
- sse_register_chn(&adc0, 0, 2, CONFIG_TIVA_ADC0_SSE0_STEP2_AIN);
- sse_differential(&adc0, 0, 2, 0);
-# if defined (CONFIG_ARCH_CHIP_TM4C129) && (CONFIG_TIVA_ADC0_SSE0_TRIGGER == ADC_EMUX_PROC)
- sse_sample_hold_time(&adc0, 0, 2, ADC_SSTH_SHOLD_16);
-# endif
-# ifndef CONFIG_TIVA_ADC0_SSE0_STEP3
- sse_step_cfg(&adc0, 0, 2, chncfg | ADC_SSCTL_END);
-# else
- sse_step_cfg(&adc0, 0, 2, chncfg);
-# endif
-# ifdef CONFIG_TIVA_ADC0_SSE0_STEP3
-# ifdef CONFIG_TIVA_ADC0_SSE0_STEP3_TS
- chncfg = ADC_SSCTL_IE | ADC_SSCTL_TS;
-# else
- chncfg = ADC_SSCTL_IE;
-# endif
- tiva_configgpio(TIVA_ADC_PIN(CONFIG_TIVA_ADC0_SSE0_STEP3_AIN));
- sse_register_chn(&adc0, 0, 3, CONFIG_TIVA_ADC0_SSE0_STEP3_AIN);
- sse_differential(&adc0, 0, 3, 0);
-# if defined (CONFIG_ARCH_CHIP_TM4C129) && (CONFIG_TIVA_ADC0_SSE0_TRIGGER == ADC_EMUX_PROC)
- sse_sample_hold_time(&adc0, 0, 3, ADC_SSTH_SHOLD_16);
-# endif
-# ifndef CONFIG_TIVA_ADC0_SSE0_STEP4
- sse_step_cfg(&adc0, 0, 3, chncfg | ADC_SSCTL_END);
-# else
- sse_step_cfg(&adc0, 0, 3, chncfg);
-# endif
-# ifdef CONFIG_TIVA_ADC0_SSE0_STEP4
-# ifdef CONFIG_TIVA_ADC0_SSE0_STEP4_TS
- chncfg = ADC_SSCTL_IE | ADC_SSCTL_TS;
-# else
- chncfg = ADC_SSCTL_IE;
-# endif
- tiva_configgpio(TIVA_ADC_PIN(CONFIG_TIVA_ADC0_SSE0_STEP4_AIN));
- sse_register_chn(&adc0, 0, 4, CONFIG_TIVA_ADC0_SSE0_STEP4_AIN);
- sse_differential(&adc0, 0, 4, 0);
-# if defined (CONFIG_ARCH_CHIP_TM4C129) && (CONFIG_TIVA_ADC0_SSE0_TRIGGER == ADC_EMUX_PROC)
- sse_sample_hold_time(&adc0, 0, 4, ADC_SSTH_SHOLD_16);
-# endif
-# ifndef CONFIG_TIVA_ADC0_SSE0_STEP5
- sse_step_cfg(&adc0, 0, 4, chncfg | ADC_SSCTL_END);
-# else
- sse_step_cfg(&adc0, 0, 4, chncfg);
-# endif
-# ifdef CONFIG_TIVA_ADC0_SSE0_STEP5
-# ifdef CONFIG_TIVA_ADC0_SSE0_STEP5_TS
- chncfg = ADC_SSCTL_IE | ADC_SSCTL_TS;
-# else
- chncfg = ADC_SSCTL_IE;
-# endif
- tiva_configgpio(TIVA_ADC_PIN(CONFIG_TIVA_ADC0_SSE0_STEP5_AIN));
- sse_register_chn(&adc0, 0, 5, CONFIG_TIVA_ADC0_SSE0_STEP5_AIN);
- sse_differential(&adc0, 0, 5, 0);
-# if defined (CONFIG_ARCH_CHIP_TM4C129) && (CONFIG_TIVA_ADC0_SSE0_TRIGGER == ADC_EMUX_PROC)
- sse_sample_hold_time(&adc0, 0, 5, ADC_SSTH_SHOLD_16);
-# endif
-# ifndef CONFIG_TIVA_ADC0_SSE0_STEP6
- sse_step_cfg(&adc0, 0, 5, chncfg | ADC_SSCTL_END);
-# else
- sse_step_cfg(&adc0, 0, 5, chncfg);
-# endif
-# ifdef CONFIG_TIVA_ADC0_SSE0_STEP6
-# ifdef CONFIG_TIVA_ADC0_SSE0_STEP6_TS
- chncfg = ADC_SSCTL_IE | ADC_SSCTL_TS;
-# else
- chncfg = ADC_SSCTL_IE;
-# endif
- tiva_configgpio(TIVA_ADC_PIN(CONFIG_TIVA_ADC0_SSE0_STEP6_AIN));
- sse_register_chn(&adc0, 0, 6, CONFIG_TIVA_ADC0_SSE0_STEP6_AIN);
- sse_differential(&adc0, 0, 6, 0);
-# if defined (CONFIG_ARCH_CHIP_TM4C129) && (CONFIG_TIVA_ADC0_SSE0_TRIGGER == ADC_EMUX_PROC)
- sse_sample_hold_time(&adc0, 0, 6, ADC_SSTH_SHOLD_16);
-# endif
-# ifndef CONFIG_TIVA_ADC0_SSE0_STEP7
- sse_step_cfg(&adc0, 0, 6, chncfg | ADC_SSCTL_END);
-# else
- sse_step_cfg(&adc0, 0, 6, chncfg);
-# endif
-# ifdef CONFIG_TIVA_ADC0_SSE0_STEP7
-# ifdef CONFIG_TIVA_ADC0_SSE0_STEP7_TS
- chncfg = ADC_SSCTL_IE | ADC_SSCTL_TS;
-# else
- chncfg = ADC_SSCTL_IE;
-# endif
- tiva_configgpio(TIVA_ADC_PIN(CONFIG_TIVA_ADC0_SSE0_STEP7_AIN));
- sse_register_chn(&adc0, 0, 7, CONFIG_TIVA_ADC0_SSE0_STEP7_AIN);
- sse_differential(&adc0, 0, 7, 0);
-# if defined (CONFIG_ARCH_CHIP_TM4C129) && (CONFIG_TIVA_ADC0_SSE0_TRIGGER == ADC_EMUX_PROC)
- sse_sample_hold_time(&adc0, 0, 7, ADC_SSTH_SHOLD_16);
-# endif
- sse_step_cfg(&adc0, 0, 7, chncfg | ADC_SSCTL_END);
-# endif /* CONFIG_TIVA_ADC0_SSE0_STEP7 */
-# endif /* CONFIG_TIVA_ADC0_SSE0_STEP6 */
-# endif /* CONFIG_TIVA_ADC0_SSE0_STEP5 */
-# endif /* CONFIG_TIVA_ADC0_SSE0_STEP4 */
-# endif /* CONFIG_TIVA_ADC0_SSE0_STEP3 */
-# endif /* CONFIG_TIVA_ADC0_SSE0_STEP2 */
-# endif /* CONFIG_TIVA_ADC0_SSE0_STEP1 */
-# endif /* CONFIG_TIVA_ADC0_SSE0_STEP0 */
-}
-# endif /* CONFIG_TIVA_ADC0_SSE0 */
-
-# ifdef CONFIG_TIVA_ADC0_SSE1
-static void adc0_sse1_chn_cfg(void)
-{
- uint32_t chncfg = 0;
-# ifdef CONFIG_TIVA_ADC0_SSE1_STEP0
-# ifdef CONFIG_TIVA_ADC0_SSE1_STEP0_TS
- chncfg = ADC_SSCTL_IE | ADC_SSCTL_TS;
-# else
- chncfg = ADC_SSCTL_IE;
-# endif
- tiva_configgpio(TIVA_ADC_PIN(CONFIG_TIVA_ADC0_SSE1_STEP0_AIN));
- sse_register_chn(&adc0, 1, 0, CONFIG_TIVA_ADC0_SSE1_STEP0_AIN);
- sse_differential(&adc0, 1, 0, 0);
-# if defined (CONFIG_ARCH_CHIP_TM4C129) && (CONFIG_TIVA_ADC0_SSE1_TRIGGER == ADC_EMUX_PROC)
- sse_sample_hold_time(&adc0, 1, 0, ADC_SSTH_SHOLD_16);
-# endif
-# ifndef CONFIG_TIVA_ADC0_SSE1_STEP1
- sse_step_cfg(&adc0, 1, 0, chncfg | ADC_SSCTL_END);
-# else
- sse_step_cfg(&adc0, 1, 0, chncfg);
-# endif
-# ifdef CONFIG_TIVA_ADC0_SSE1_STEP1
-# ifdef CONFIG_TIVA_ADC0_SSE1_STEP1_TS
- chncfg = ADC_SSCTL_IE | ADC_SSCTL_TS;
-# else
- chncfg = ADC_SSCTL_IE;
-# endif
- tiva_configgpio(TIVA_ADC_PIN(CONFIG_TIVA_ADC0_SSE1_STEP1_AIN));
- sse_register_chn(&adc0, 1, 1, CONFIG_TIVA_ADC0_SSE1_STEP1_AIN);
- sse_differential(&adc0, 1, 1, 0);
-# if defined (CONFIG_ARCH_CHIP_TM4C129) && (CONFIG_TIVA_ADC0_SSE1_TRIGGER == ADC_EMUX_PROC)
- sse_sample_hold_time(&adc0, 1, 1, ADC_SSTH_SHOLD_16);
-# endif
-# ifndef CONFIG_TIVA_ADC0_SSE1_STEP2
- sse_step_cfg(&adc0, 1, 1, chncfg | ADC_SSCTL_END);
-# else
- sse_step_cfg(&adc0, 1, 1, chncfg);
-# endif
-# ifdef CONFIG_TIVA_ADC0_SSE1_STEP2
-# ifdef CONFIG_TIVA_ADC0_SSE1_STEP2_TS
- chncfg = ADC_SSCTL_IE | ADC_SSCTL_TS;
-# else
- chncfg = ADC_SSCTL_IE;
-# endif
- tiva_configgpio(TIVA_ADC_PIN(CONFIG_TIVA_ADC0_SSE1_STEP2_AIN));
- sse_register_chn(&adc0, 1, 2, CONFIG_TIVA_ADC0_SSE1_STEP2_AIN);
- sse_differential(&adc0, 1, 2, 0);
-# if defined (CONFIG_ARCH_CHIP_TM4C129) && (CONFIG_TIVA_ADC0_SSE1_TRIGGER == ADC_EMUX_PROC)
- sse_sample_hold_time(&adc0, 1, 2, ADC_SSTH_SHOLD_16);
-# endif
-# ifndef CONFIG_TIVA_ADC0_SSE1_STEP3
- sse_step_cfg(&adc0, 1, 2, chncfg | ADC_SSCTL_END);
-# else
- sse_step_cfg(&adc0, 1, 2, chncfg);
-# endif
-# ifdef CONFIG_TIVA_ADC0_SSE1_STEP3
-# ifdef CONFIG_TIVA_ADC0_SSE1_STEP3_TS
- chncfg = ADC_SSCTL_IE | ADC_SSCTL_TS;
-# else
- chncfg = ADC_SSCTL_IE;
-# endif
- tiva_configgpio(TIVA_ADC_PIN(CONFIG_TIVA_ADC0_SSE1_STEP3_AIN));
- sse_register_chn(&adc0, 1, 3, CONFIG_TIVA_ADC0_SSE1_STEP3_AIN);
- sse_differential(&adc0, 1, 3, 0);
-# if defined (CONFIG_ARCH_CHIP_TM4C129) && (CONFIG_TIVA_ADC0_SSE1_TRIGGER == ADC_EMUX_PROC)
- sse_sample_hold_time(&adc0, 1, 3, ADC_SSTH_SHOLD_16);
-# endif
- sse_step_cfg(&adc0, 1, 3, chncfg | ADC_SSCTL_END);
-# endif /* CONFIG_TIVA_ADC0_SSE1_STEP3 */
-# endif /* CONFIG_TIVA_ADC0_SSE1_STEP2 */
-# endif /* CONFIG_TIVA_ADC0_SSE1_STEP1 */
-# endif /* CONFIG_TIVA_ADC0_SSE1_STEP0 */
-}
-# endif /* CONFIG_TIVA_ADC0_SSE1 */
-
-# ifdef CONFIG_TIVA_ADC0_SSE2
-static void adc0_sse2_chn_cfg(void)
-{
- uint32_t chncfg = 0;
-# ifdef CONFIG_TIVA_ADC0_SSE2_STEP0
-# ifdef CONFIG_TIVA_ADC0_SSE2_STEP0_TS
- chncfg = ADC_SSCTL_IE | ADC_SSCTL_TS;
-# else
- chncfg = ADC_SSCTL_IE;
-# endif
- tiva_configgpio(TIVA_ADC_PIN(CONFIG_TIVA_ADC0_SSE2_STEP0_AIN));
- sse_register_chn(&adc0, 2, 0, CONFIG_TIVA_ADC0_SSE2_STEP0_AIN);
- sse_differential(&adc0, 2, 0, 0);
-# if defined (CONFIG_ARCH_CHIP_TM4C129) && (CONFIG_TIVA_ADC0_SSE2_TRIGGER == ADC_EMUX_PROC)
- sse_sample_hold_time(&adc0, 2, 0, ADC_SSTH_SHOLD_16);
-# endif
-# ifndef CONFIG_TIVA_ADC0_SSE2_STEP1
- sse_step_cfg(&adc0, 2, 0, chncfg | ADC_SSCTL_END);
-# else
- sse_step_cfg(&adc0, 2, 0, chncfg);
-# endif
-# ifdef CONFIG_TIVA_ADC0_SSE2_STEP1
-# ifdef CONFIG_TIVA_ADC0_SSE2_STEP1_TS
- chncfg = ADC_SSCTL_IE | ADC_SSCTL_TS;
-# else
- chncfg = ADC_SSCTL_IE;
-# endif
- tiva_configgpio(TIVA_ADC_PIN(CONFIG_TIVA_ADC0_SSE2_STEP1_AIN));
- sse_register_chn(&adc0, 2, 1, CONFIG_TIVA_ADC0_SSE2_STEP1_AIN);
- sse_differential(&adc0, 2, 1, 0);
-# if defined (CONFIG_ARCH_CHIP_TM4C129) && (CONFIG_TIVA_ADC0_SSE2_TRIGGER == ADC_EMUX_PROC)
- sse_sample_hold_time(&adc0, 2, 1, ADC_SSTH_SHOLD_16);
-# endif
-# ifndef CONFIG_TIVA_ADC0_SSE2_STEP2
- sse_step_cfg(&adc0, 2, 1, chncfg | ADC_SSCTL_END);
-# else
- sse_step_cfg(&adc0, 2, 1, chncfg);
-# endif
-# ifdef CONFIG_TIVA_ADC0_SSE2_STEP2
-# ifdef CONFIG_TIVA_ADC0_SSE2_STEP2_TS
- chncfg = ADC_SSCTL_IE | ADC_SSCTL_TS;
-# else
- chncfg = ADC_SSCTL_IE;
-# endif
- tiva_configgpio(TIVA_ADC_PIN(CONFIG_TIVA_ADC0_SSE2_STEP2_AIN));
- sse_register_chn(&adc0, 2, 2, CONFIG_TIVA_ADC0_SSE2_STEP2_AIN);
- sse_differential(&adc0, 2, 2, 0);
-# if defined (CONFIG_ARCH_CHIP_TM4C129) && (CONFIG_TIVA_ADC0_SSE2_TRIGGER == ADC_EMUX_PROC)
- sse_sample_hold_time(&adc0, 2, 2, ADC_SSTH_SHOLD_16);
-# endif
-# ifndef CONFIG_TIVA_ADC0_SSE2_STEP3
- sse_step_cfg(&adc0, 2, 2, chncfg | ADC_SSCTL_END);
-# else
- sse_step_cfg(&adc0, 2, 2, chncfg);
-# endif
-# ifdef CONFIG_TIVA_ADC0_SSE2_STEP3
-# ifdef CONFIG_TIVA_ADC0_SSE2_STEP3_TS
- chncfg = ADC_SSCTL_IE | ADC_SSCTL_TS;
-# else
- chncfg = ADC_SSCTL_IE;
-# endif
- tiva_configgpio(TIVA_ADC_PIN(CONFIG_TIVA_ADC0_SSE2_STEP3_AIN));
- sse_register_chn(&adc0, 2, 3, CONFIG_TIVA_ADC0_SSE2_STEP3_AIN);
- sse_differential(&adc0, 2, 3, 0);
-# if defined (CONFIG_ARCH_CHIP_TM4C129) && (CONFIG_TIVA_ADC0_SSE2_TRIGGER == ADC_EMUX_PROC)
- sse_sample_hold_time(&adc0, 2, 3, ADC_SSTH_SHOLD_16);
-# endif
- sse_step_cfg(&adc0, 2, 3, chncfg | ADC_SSCTL_END);
-# endif /* CONFIG_TIVA_ADC0_SSE2_STEP3 */
-# endif /* CONFIG_TIVA_ADC0_SSE2_STEP2 */
-# endif /* CONFIG_TIVA_ADC0_SSE2_STEP1 */
-# endif /* CONFIG_TIVA_ADC0_SSE2_STEP0 */
-}
-# endif /* CONFIG_TIVA_ADC0_SSE2 */
-
-# ifdef CONFIG_TIVA_ADC0_SSE3
-static void adc0_sse3_chn_cfg(void)
-{
- uint32_t chncfg = 0;
-# ifdef CONFIG_TIVA_ADC0_SSE3_STEP0
-# ifdef CONFIG_TIVA_ADC0_SSE3_STEP0_TS
- chncfg = ADC_SSCTL_IE | ADC_SSCTL_TS;
-# else
- chncfg = ADC_SSCTL_IE;
-# endif
- tiva_configgpio(TIVA_ADC_PIN(CONFIG_TIVA_ADC0_SSE3_STEP0_AIN));
- sse_register_chn(&adc0, 3, 0, CONFIG_TIVA_ADC0_SSE3_STEP0_AIN);
- sse_differential(&adc0, 3, 0, 0);
-# if defined (CONFIG_ARCH_CHIP_TM4C129) && (CONFIG_TIVA_ADC0_SSE3_TRIGGER == ADC_EMUX_PROC)
- sse_sample_hold_time(&adc0, 3, 0, ADC_SSTH_SHOLD_16);
-# endif
- sse_step_cfg(&adc0, 3, 0, chncfg | ADC_SSCTL_END);
-# endif /* CONFIG_TIVA_ADC0_SSE3_STEP0 */
-}
-# endif /* CONFIG_TIVA_ADC0_SSE3 */
-#endif /* CONFIG_TIVA_ADC0 */
-
-#ifdef CONFIG_TIVA_ADC1
-# ifdef CONFIG_TIVA_ADC1_SSE0
-static void adc1_sse0_chn_cfg(void)
-{
- uint32_t chncfg = 0;
-# ifdef CONFIG_TIVA_ADC1_SSE0_STEP0
-# ifdef CONFIG_TIVA_ADC1_SSE0_STEP0_TS
- chncfg = ADC_SSCTL_IE | ADC_SSCTL_TS;
-# else
- chncfg = ADC_SSCTL_IE;
-# endif
- tiva_configgpio(TIVA_ADC_PIN(CONFIG_TIVA_ADC1_SSE0_STEP0_AIN));
- sse_register_chn(&adc1, 0, 0, CONFIG_TIVA_ADC1_SSE0_STEP0_AIN);
- sse_differential(&adc1, 0, 0, 0);
-# if defined (CONFIG_ARCH_CHIP_TM4C129) && (CONFIG_TIVA_ADC1_SSE0_TRIGGER == ADC_EMUX_PROC)
- sse_sample_hold_time(&adc1, 0, 0, ADC_SSTH_SHOLD_16);
-# endif
-# ifndef CONFIG_TIVA_ADC1_SSE0_STEP1
- sse_step_cfg(&adc1, 0, 0, chncfg | ADC_SSCTL_END);
-# else
- sse_step_cfg(&adc1, 0, 0, chncfg);
-# endif
-# ifdef CONFIG_TIVA_ADC1_SSE0_STEP1
-# ifdef CONFIG_TIVA_ADC1_SSE0_STEP1_TS
- chncfg = ADC_SSCTL_IE | ADC_SSCTL_TS;
-# else
- chncfg = ADC_SSCTL_IE;
-# endif
- tiva_configgpio(TIVA_ADC_PIN(CONFIG_TIVA_ADC1_SSE0_STEP1_AIN));
- sse_register_chn(&adc1, 0, 1, CONFIG_TIVA_ADC1_SSE0_STEP1_AIN);
- sse_differential(&adc1, 0, 1, 0);
-# if defined (CONFIG_ARCH_CHIP_TM4C129) && (CONFIG_TIVA_ADC1_SSE0_TRIGGER == ADC_EMUX_PROC)
- sse_sample_hold_time(&adc1, 0, 1, ADC_SSTH_SHOLD_16);
-# endif
-# ifndef CONFIG_TIVA_ADC1_SSE0_STEP2
- sse_step_cfg(&adc1, 0, 1, chncfg | ADC_SSCTL_END);
-# else
- sse_step_cfg(&adc1, 0, 1, chncfg);
-# endif
-# ifdef CONFIG_TIVA_ADC1_SSE0_STEP2
-# ifdef CONFIG_TIVA_ADC1_SSE0_STEP2_TS
- chncfg = ADC_SSCTL_IE | ADC_SSCTL_TS;
-# else
- chncfg = ADC_SSCTL_IE;
-# endif
- tiva_configgpio(TIVA_ADC_PIN(CONFIG_TIVA_ADC1_SSE0_STEP2_AIN));
- sse_register_chn(&adc1, 0, 2, CONFIG_TIVA_ADC1_SSE0_STEP2_AIN);
- sse_differential(&adc1, 0, 2, 0);
-# if defined (CONFIG_ARCH_CHIP_TM4C129) && (CONFIG_TIVA_ADC1_SSE0_TRIGGER == ADC_EMUX_PROC)
- sse_sample_hold_time(&adc1, 0, 2, ADC_SSTH_SHOLD_16);
-# endif
-# ifndef CONFIG_TIVA_ADC1_SSE0_STEP3
- sse_step_cfg(&adc1, 0, 2, chncfg | ADC_SSCTL_END);
-# else
- sse_step_cfg(&adc1, 0, 2, chncfg);
-# endif
-# ifdef CONFIG_TIVA_ADC1_SSE0_STEP3
-# ifdef CONFIG_TIVA_ADC1_SSE0_STEP3_TS
- chncfg = ADC_SSCTL_IE | ADC_SSCTL_TS;
-# else
- chncfg = ADC_SSCTL_IE;
-# endif
- tiva_configgpio(TIVA_ADC_PIN(CONFIG_TIVA_ADC1_SSE0_STEP3_AIN));
- sse_register_chn(&adc1, 0, 3, CONFIG_TIVA_ADC1_SSE0_STEP3_AIN);
- sse_differential(&adc1, 0, 3, 0);
-# if defined (CONFIG_ARCH_CHIP_TM4C129) && (CONFIG_TIVA_ADC1_SSE0_TRIGGER == ADC_EMUX_PROC)
- sse_sample_hold_time(&adc1, 0, 3, ADC_SSTH_SHOLD_16);
-# endif
-# ifndef CONFIG_TIVA_ADC1_SSE0_STEP4
- sse_step_cfg(&adc1, 0, 3, chncfg | ADC_SSCTL_END);
-# else
- sse_step_cfg(&adc1, 0, 3, chncfg);
-# endif
-# ifdef CONFIG_TIVA_ADC1_SSE0_STEP4
-# ifdef CONFIG_TIVA_ADC1_SSE0_STEP4_TS
- chncfg = ADC_SSCTL_IE | ADC_SSCTL_TS;
-# else
- chncfg = ADC_SSCTL_IE;
-# endif
- tiva_configgpio(TIVA_ADC_PIN(CONFIG_TIVA_ADC1_SSE0_STEP4_AIN));
- sse_register_chn(&adc1, 0, 4, CONFIG_TIVA_ADC1_SSE0_STEP4_AIN);
- sse_differential(&adc1, 0, 4, 0);
-# if defined (CONFIG_ARCH_CHIP_TM4C129) && (CONFIG_TIVA_ADC1_SSE0_TRIGGER == ADC_EMUX_PROC)
- sse_sample_hold_time(&adc1, 0, 4, ADC_SSTH_SHOLD_16);
-# endif
-# ifndef CONFIG_TIVA_ADC1_SSE0_STEP5
- sse_step_cfg(&adc1, 0, 4, chncfg | ADC_SSCTL_END);
-# else
- sse_step_cfg(&adc1, 0, 4, chncfg);
-# endif
-# ifdef CONFIG_TIVA_ADC1_SSE0_STEP5
-# ifdef CONFIG_TIVA_ADC1_SSE0_STEP5_TS
- chncfg = ADC_SSCTL_IE | ADC_SSCTL_TS;
-# else
- chncfg = ADC_SSCTL_IE;
-# endif
- tiva_configgpio(TIVA_ADC_PIN(CONFIG_TIVA_ADC1_SSE0_STEP5_AIN));
- sse_register_chn(&adc1, 0, 5, CONFIG_TIVA_ADC1_SSE0_STEP5_AIN);
- sse_differential(&adc1, 0, 5, 0);
-# if defined (CONFIG_ARCH_CHIP_TM4C129) && (CONFIG_TIVA_ADC1_SSE0_TRIGGER == ADC_EMUX_PROC)
- sse_sample_hold_time(&adc1, 0, 5, ADC_SSTH_SHOLD_16);
-# endif
-# ifndef CONFIG_TIVA_ADC1_SSE0_STEP6
- sse_step_cfg(&adc1, 0, 5, chncfg | ADC_SSCTL_END);
-# else
- sse_step_cfg(&adc1, 0, 5, chncfg);
-# endif
-# ifdef CONFIG_TIVA_ADC1_SSE0_STEP6
-# ifdef CONFIG_TIVA_ADC1_SSE0_STEP6_TS
- chncfg = ADC_SSCTL_IE | ADC_SSCTL_TS;
-# else
- chncfg = ADC_SSCTL_IE;
-# endif
- tiva_configgpio(TIVA_ADC_PIN(CONFIG_TIVA_ADC1_SSE0_STEP6_AIN));
- sse_register_chn(&adc1, 0, 6, CONFIG_TIVA_ADC1_SSE0_STEP6_AIN);
- sse_differential(&adc1, 0, 6, 0);
-# if defined (CONFIG_ARCH_CHIP_TM4C129) && (CONFIG_TIVA_ADC1_SSE0_TRIGGER == ADC_EMUX_PROC)
- sse_sample_hold_time(&adc1, 0, 6, ADC_SSTH_SHOLD_16);
-# endif
-# ifndef CONFIG_TIVA_ADC1_SSE0_STEP7
- sse_step_cfg(&adc1, 0, 6, chncfg | ADC_SSCTL_END);
-# else
- sse_step_cfg(&adc1, 0, 6, chncfg);
-# endif
-# ifdef CONFIG_TIVA_ADC1_SSE0_STEP7
-# ifdef CONFIG_TIVA_ADC1_SSE0_STEP7_TS
- chncfg = ADC_SSCTL_IE | ADC_SSCTL_TS;
-# else
- chncfg = ADC_SSCTL_IE;
-# endif
- tiva_configgpio(TIVA_ADC_PIN(CONFIG_TIVA_ADC1_SSE0_STEP7_AIN));
- sse_register_chn(&adc1, 0, 7, CONFIG_TIVA_ADC1_SSE0_STEP7_AIN);
- sse_differential(&adc1, 0, 7, 0);
-# if defined (CONFIG_ARCH_CHIP_TM4C129) && (CONFIG_TIVA_ADC1_SSE0_TRIGGER == ADC_EMUX_PROC)
- sse_sample_hold_time(&adc1, 0, 7, ADC_SSTH_SHOLD_16);
-# endif
- sse_step_cfg(&adc1, 0, 7, chncfg | ADC_SSCTL_END);
-# endif /* CONFIG_TIVA_ADC1_SSE0_STEP7 */
-# endif /* CONFIG_TIVA_ADC1_SSE0_STEP6 */
-# endif /* CONFIG_TIVA_ADC1_SSE0_STEP5 */
-# endif /* CONFIG_TIVA_ADC1_SSE0_STEP4 */
-# endif /* CONFIG_TIVA_ADC1_SSE0_STEP3 */
-# endif /* CONFIG_TIVA_ADC1_SSE0_STEP2 */
-# endif /* CONFIG_TIVA_ADC1_SSE0_STEP1 */
-# endif /* CONFIG_TIVA_ADC1_SSE0_STEP0 */
-}
-# endif /* CONFIG_TIVA_ADC1_SSE0 */
-
-# ifdef CONFIG_TIVA_ADC1_SSE1
-static void adc1_sse1_chn_cfg(void)
-{
- uint32_t chncfg = 0;
-# ifdef CONFIG_TIVA_ADC1_SSE1_STEP0
-# ifdef CONFIG_TIVA_ADC1_SSE1_STEP0_TS
- chncfg = ADC_SSCTL_IE | ADC_SSCTL_TS;
-# else
- chncfg = ADC_SSCTL_IE;
-# endif
- tiva_configgpio(TIVA_ADC_PIN(CONFIG_TIVA_ADC1_SSE1_STEP0_AIN));
- sse_register_chn(&adc1, 1, 0, CONFIG_TIVA_ADC1_SSE1_STEP0_AIN);
- sse_differential(&adc1, 1, 0, 0);
-# if defined (CONFIG_ARCH_CHIP_TM4C129) && (CONFIG_TIVA_ADC1_SSE1_TRIGGER == ADC_EMUX_PROC)
- sse_sample_hold_time(&adc1, 1, 0, ADC_SSTH_SHOLD_16);
-# endif
-# ifndef CONFIG_TIVA_ADC1_SSE1_STEP1
- sse_step_cfg(&adc1, 1, 0, chncfg | ADC_SSCTL_END);
-# else
- sse_step_cfg(&adc1, 1, 0, chncfg);
-# endif
-# ifdef CONFIG_TIVA_ADC1_SSE1_STEP1
-# ifdef CONFIG_TIVA_ADC1_SSE1_STEP1_TS
- chncfg = ADC_SSCTL_IE | ADC_SSCTL_TS;
-# else
- chncfg = ADC_SSCTL_IE;
-# endif
- tiva_configgpio(TIVA_ADC_PIN(CONFIG_TIVA_ADC1_SSE1_STEP1_AIN));
- sse_register_chn(&adc1, 1, 1, CONFIG_TIVA_ADC1_SSE1_STEP1_AIN);
- sse_differential(&adc1, 1, 1, 0);
-# if defined (CONFIG_ARCH_CHIP_TM4C129) && (CONFIG_TIVA_ADC1_SSE1_TRIGGER == ADC_EMUX_PROC)
- sse_sample_hold_time(&adc1, 1, 1, ADC_SSTH_SHOLD_16);
-# endif
-# ifndef CONFIG_TIVA_ADC1_SSE1_STEP2
- sse_step_cfg(&adc1, 1, 1, chncfg | ADC_SSCTL_END);
-# else
- sse_step_cfg(&adc1, 1, 1, chncfg);
-# endif
-# ifdef CONFIG_TIVA_ADC1_SSE1_STEP2
-# ifdef CONFIG_TIVA_ADC1_SSE1_STEP2_TS
- chncfg = ADC_SSCTL_IE | ADC_SSCTL_TS;
-# else
- chncfg = ADC_SSCTL_IE;
-# endif
- tiva_configgpio(TIVA_ADC_PIN(CONFIG_TIVA_ADC1_SSE1_STEP2_AIN));
- sse_register_chn(&adc1, 1, 2, CONFIG_TIVA_ADC1_SSE1_STEP2_AIN);
- sse_differential(&adc1, 1, 2, 0);
-# if defined (CONFIG_ARCH_CHIP_TM4C129) && (CONFIG_TIVA_ADC1_SSE1_TRIGGER == ADC_EMUX_PROC)
- sse_sample_hold_time(&adc1, 1, 2, ADC_SSTH_SHOLD_16);
-# endif
-# ifndef CONFIG_TIVA_ADC1_SSE1_STEP3
- sse_step_cfg(&adc1, 1, 2, chncfg | ADC_SSCTL_END);
-# else
- sse_step_cfg(&adc1, 1, 2, chncfg);
-# endif
-# ifdef CONFIG_TIVA_ADC1_SSE1_STEP3
-# ifdef CONFIG_TIVA_ADC1_SSE1_STEP3_TS
- chncfg = ADC_SSCTL_IE | ADC_SSCTL_TS;
-# else
- chncfg = ADC_SSCTL_IE;
-# endif
- tiva_configgpio(TIVA_ADC_PIN(CONFIG_TIVA_ADC1_SSE1_STEP3_AIN));
- sse_register_chn(&adc1, 1, 3, CONFIG_TIVA_ADC1_SSE1_STEP3_AIN);
- sse_differential(&adc1, 1, 3, 0);
-# if defined (CONFIG_ARCH_CHIP_TM4C129) && (CONFIG_TIVA_ADC1_SSE1_TRIGGER == ADC_EMUX_PROC)
- sse_sample_hold_time(&adc1, 1, 3, ADC_SSTH_SHOLD_16);
-# endif
- sse_step_cfg(&adc1, 1, 3, chncfg | ADC_SSCTL_END);
-# endif /* CONFIG_TIVA_ADC1_SSE1_STEP3 */
-# endif /* CONFIG_TIVA_ADC1_SSE1_STEP2 */
-# endif /* CONFIG_TIVA_ADC1_SSE1_STEP1 */
-# endif /* CONFIG_TIVA_ADC1_SSE1_STEP0 */
-}
-# endif /* CONFIG_TIVA_ADC1_SSE1 */
-
-# ifdef CONFIG_TIVA_ADC1_SSE2
-static void adc1_sse2_chn_cfg(void)
-{
- uint32_t chncfg = 0;
-# ifdef CONFIG_TIVA_ADC1_SSE2_STEP0
-# ifdef CONFIG_TIVA_ADC1_SSE2_STEP0_TS
- chncfg = ADC_SSCTL_IE | ADC_SSCTL_TS;
-# else
- chncfg = ADC_SSCTL_IE;
-# endif
- tiva_configgpio(TIVA_ADC_PIN(CONFIG_TIVA_ADC1_SSE2_STEP0_AIN));
- sse_register_chn(&adc1, 2, 0, CONFIG_TIVA_ADC1_SSE2_STEP0_AIN);
- sse_differential(&adc1, 2, 0, 0);
-# if defined (CONFIG_ARCH_CHIP_TM4C129) && (CONFIG_TIVA_ADC1_SSE2_TRIGGER == ADC_EMUX_PROC)
- sse_sample_hold_time(&adc1, 2, 0, ADC_SSTH_SHOLD_16);
-# endif
-# ifndef CONFIG_TIVA_ADC1_SSE2_STEP1
- sse_step_cfg(&adc1, 2, 0, chncfg | ADC_SSCTL_END);
-# else
- sse_step_cfg(&adc1, 2, 0, chncfg);
-# endif
-# ifdef CONFIG_TIVA_ADC1_SSE2_STEP1
-# ifdef CONFIG_TIVA_ADC1_SSE2_STEP1_TS
- chncfg = ADC_SSCTL_IE | ADC_SSCTL_TS;
-# else
- chncfg = ADC_SSCTL_IE;
-# endif
- tiva_configgpio(TIVA_ADC_PIN(CONFIG_TIVA_ADC1_SSE2_STEP1_AIN));
- sse_register_chn(&adc1, 2, 1, CONFIG_TIVA_ADC1_SSE2_STEP1_AIN);
- sse_differential(&adc1, 2, 1, 0);
-# if defined (CONFIG_ARCH_CHIP_TM4C129) && (CONFIG_TIVA_ADC1_SSE2_TRIGGER == ADC_EMUX_PROC)
- sse_sample_hold_time(&adc1, 2, 1, ADC_SSTH_SHOLD_16);
-# endif
-# ifndef CONFIG_TIVA_ADC1_SSE2_STEP2
- sse_step_cfg(&adc1, 2, 1, chncfg | ADC_SSCTL_END);
-# else
- sse_step_cfg(&adc1, 2, 1, chncfg);
-# endif
-# ifdef CONFIG_TIVA_ADC1_SSE2_STEP2
-# ifdef CONFIG_TIVA_ADC1_SSE2_STEP2_TS
- chncfg = ADC_SSCTL_IE | ADC_SSCTL_TS;
-# else
- chncfg = ADC_SSCTL_IE;
-# endif
- tiva_configgpio(TIVA_ADC_PIN(CONFIG_TIVA_ADC1_SSE2_STEP2_AIN));
- sse_register_chn(&adc1, 2, 2, CONFIG_TIVA_ADC1_SSE2_STEP2_AIN);
- sse_differential(&adc1, 2, 2, 0);
-# if defined (CONFIG_ARCH_CHIP_TM4C129) && (CONFIG_TIVA_ADC1_SSE2_TRIGGER == ADC_EMUX_PROC)
- sse_sample_hold_time(&adc1, 2, 2, ADC_SSTH_SHOLD_16);
-# endif
-# ifndef CONFIG_TIVA_ADC1_SSE2_STEP3
- sse_step_cfg(&adc1, 2, 2, chncfg | ADC_SSCTL_END);
-# else
- sse_step_cfg(&adc1, 2, 2, chncfg);
-# endif
-# ifdef CONFIG_TIVA_ADC1_SSE2_STEP3
-# ifdef CONFIG_TIVA_ADC1_SSE2_STEP3_TS
- chncfg = ADC_SSCTL_IE | ADC_SSCTL_TS;
-# else
- chncfg = ADC_SSCTL_IE;
-# endif
- tiva_configgpio(TIVA_ADC_PIN(CONFIG_TIVA_ADC1_SSE2_STEP3_AIN));
- sse_register_chn(&adc1, 2, 3, CONFIG_TIVA_ADC1_SSE2_STEP3_AIN);
- sse_differential(&adc1, 2, 3, 0);
-# if defined (CONFIG_ARCH_CHIP_TM4C129) && (CONFIG_TIVA_ADC1_SSE2_TRIGGER == ADC_EMUX_PROC)
- sse_sample_hold_time(&adc1, 2, 3, ADC_SSTH_SHOLD_16);
-# endif
- sse_step_cfg(&adc1, 2, 3, chncfg | ADC_SSCTL_END);
-# endif /* CONFIG_TIVA_ADC1_SSE2_STEP3 */
-# endif /* CONFIG_TIVA_ADC1_SSE2_STEP2 */
-# endif /* CONFIG_TIVA_ADC1_SSE2_STEP1 */
-# endif /* CONFIG_TIVA_ADC1_SSE2_STEP0 */
-}
-# endif /* CONFIG_TIVA_ADC1_SSE2 */
-
-# ifdef CONFIG_TIVA_ADC1_SSE3
-static void adc1_sse3_chn_cfg(void)
-{
- uint32_t chncfg = 0;
-# ifdef CONFIG_TIVA_ADC1_SSE3_STEP0
-# ifdef CONFIG_TIVA_ADC1_SSE3_STEP0_TS
- chncfg = ADC_SSCTL_IE | ADC_SSCTL_TS;
-# else
- chncfg = ADC_SSCTL_IE;
-# endif
- tiva_configgpio(TIVA_ADC_PIN(CONFIG_TIVA_ADC1_SSE3_STEP0_AIN));
- sse_register_chn(&adc1, 3, 0, CONFIG_TIVA_ADC1_SSE3_STEP0_AIN);
- sse_differential(&adc1, 3, 0, 0);
-# if defined (CONFIG_ARCH_CHIP_TM4C129) && (CONFIG_TIVA_ADC1_SSE3_TRIGGER == ADC_EMUX_PROC)
- sse_sample_hold_time(&adc1, 3, 0, ADC_SSTH_SHOLD_16);
-# endif
- sse_step_cfg(&adc1, 3, 0, chncfg | ADC_SSCTL_END);
-# endif /* CONFIG_TIVA_ADC1_SSE3_STEP0 */
-}
-# endif /* CONFIG_TIVA_ADC1_SSE3 */
-#endif /* CONFIG_TIVA_ADC1 */
-
-#endif /* CONFIG_TIVA_ADC0 | CONFIG_TIVA_ADC1 */
diff --git a/nuttx/arch/arm/src/tiva/tiva_adc.h b/nuttx/arch/arm/src/tiva/tiva_adc.h
index aa86a9be8..3b9f6feac 100644
--- a/nuttx/arch/arm/src/tiva/tiva_adc.h
+++ b/nuttx/arch/arm/src/tiva/tiva_adc.h
@@ -41,11 +41,10 @@
****************************************************************************/
#include <nuttx/config.h>
-#include <nuttx/analog/adc.h>
#include <nuttx/fs/ioctl.h>
+#include <nuttx/irq.h>
#include "chip.h"
-#include "chip/tiva_adc.h"
#ifdef CONFIG_TIVA_ADC
@@ -53,37 +52,155 @@
* Pre-processor Definitions
****************************************************************************/
+#ifndef CONFIG_DEBUG
+# undef CONFIG_TIVA_ADC_REGDEBUG
+#endif
+
+/* ADC Configuration values */
+
+#ifdef CONFIG_ARCH_CHIP_TM4C123
+# define TIVA_ADC_CLOCK_MAX (16000000)
+# define TIVA_ADC_CLOCK_MIN (16000000)
+#elif CONFIG_ARCH_CHIP_TM4C129
+# define TIVA_ADC_CLOCK_MAX (32000000)
+# define TIVA_ADC_CLOCK_MIN (16000000)
+#else
+# error TIVA_tiva_adc_clock: unsupported architecture
+#endif
+
+/* Allow the same function call to be used for sample rate */
+
+#ifdef CONFIG_ARCH_CHIP_TM4C123
+# define TIVA_ADC_SAMPLE_RATE_SLOWEST (ADC_PC_SR_125K)
+# define TIVA_ADC_SAMPLE_RATE_SLOW (ADC_PC_SR_250K)
+# define TIVA_ADC_SAMPLE_RATE_FAST (ADC_PC_SR_500K)
+# define TIVA_ADC_SAMPLE_RATE_FASTEST (ADC_PC_SR_1M)
+#elif CONFIG_ARCH_CHIP_TM4C129
+# define TIVA_ADC_SAMPLE_RATE_SLOWEST (ADC_PC_MCR_1_8)
+# define TIVA_ADC_SAMPLE_RATE_SLOW (ADC_PC_MCR_1_4)
+# define TIVA_ADC_SAMPLE_RATE_FAST (ADC_PC_MCR_1_2)
+# define TIVA_ADC_SAMPLE_RATE_FASTEST (ADC_PC_MCR_FULL)
+#else
+# error TIVA_ADC_SAMPLE_RATE: unsupported architecture
+#endif
+
+/* Sample Sequencer triggers */
+
+#define TIVA_ADC_TRIG_SW (ADC_EMUX_PROC) /* Processor (default) */
+#define TIVA_ADC_TRIG_EXTERNAL (ADC_EMUX_EXTERNAL) /* External (GPIO Pins) */
+#define TIVA_ADC_TRIG_TIMER (ADC_EMUX_TIMER) /* Timer */
+#define TIVA_ADC_TRIG_PWM0 (ADC_EMUX_PWM0) /* PWM generator 0 */
+#define TIVA_ADC_TRIG_PWM1 (ADC_EMUX_PWM1) /* PWM generator 1 */
+#define TIVA_ADC_TRIG_PWM2 (ADC_EMUX_PWM2) /* PWM generator 2 */
+#define TIVA_ADC_TRIG_PWM3 (ADC_EMUX_PWM3) /* PWM generator 3 */
+#define TIVA_ADC_TRIG_NEVER (ADC_EMUX_NEVER) /* Never Trigger */
+#define TIVA_ADC_TRIG_ALWAYS (ADC_EMUX_ALWAYS) /* Always (continuously sample) */
+
+/* Step configuration */
+
+#define TIVA_ADC_FLAG_TS (ADC_SSCTL_TS) /* Sample Temp Sensor Select */
+#define TIVA_ADC_FLAG_IE (ADC_SSCTL_IE) /* Sample Interrupt Enable */
+#define TIVA_ADC_FLAG_END (ADC_SSCTL_END) /* Sample is End of Sequence */
+
#define TIVA_ADC_PWM_TRIG_IOCTL _ANIOC(0x00F0)
/* PWM trigger ioctl support ***********************************************/
-#define TIVA_ADC_PWM_TRIG(sse, pwm, mod) ((((mod) << 4) << ((pwm) * 8)) + (sse))
+#define TIVA_ADC_PWM_TRIG(sse, pwm, mod) \
+ ((((mod) << 4) << ((pwm) * 8)) + (sse))
+
+/* Misc utility *************************************************************/
+
+#define ADC_PER_CHIP 2
+#define SSE_PER_ADC 4
+#define SSE_IDX(a,s) (((a)*SSE_PER_ADC) + (s))
/****************************************************************************
- * Public Functions
+ * Public Types
****************************************************************************/
#ifndef __ASSEMBLY__
-# ifdef __cplusplus
-# define EXTERN extern "C"
+
+/* Step configuration options */
+
+struct tiva_adc_step_cfg_s
+{
+ uint8_t adc; /* Parent peripheral */
+ uint8_t sse; /* Parent sample sequencer (SSE) */
+ uint8_t step; /* Which step in the sequencer */
+ uint8_t shold; /* Sample and hold time */
+ uint8_t flags; /* Last step? Interrupt enabled?
+ * Internal temperature sensor? */
+ uint8_t ain; /* Which analog input */
+};
+
+/* Sample Sequencer configuration options */
+
+struct tiva_adc_sse_cfg_s
+{
+ uint8_t priority; /* Conversion priority, 0-3 no duplicates */
+ uint8_t trigger; /* Trigger source */
+};
+
+/* ADC peripheral configuration options */
+
+struct tiva_adc_cfg_s
+{
+ uint8_t adc; /* ADC peripheral number */
+ bool sse[4]; /* active SSEs in a bitmask */
+ struct tiva_adc_sse_cfg_s ssecfg[4]; /* SSE configuration */
+ uint8_t steps; /* Size of the stepcfg array */
+ struct tiva_adc_step_cfg_s *stepcfg; /* Step configuration array */
+};
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
extern "C"
{
-# else
-# define EXTERN extern
+#else
+#define EXTERN extern
#endif
/****************************************************************************
+ * Inline Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/* Only allow access to upper level ADC drivers if they are enabled */
+#ifdef CONFIG_ADC
+
+/****************************************************************************
+ * Driver Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
* Name: tiva_adc_initialize
*
* Description:
- * Initialize the ADC
+ * Configuration and bind the ADC to the ADC lower half instance and
+ * register the ADC driver at 'devpath'.
*
- * Returned Value:
- * Valid can device structure reference on succcess; a NULL on failure
+ * Input Parameters:
+ * devpath - The full path to the ADC device. This should be of the
+ * form /dev/adc0
+ * cfg - ADC configuration structure, configures the whole ADC.
+ * clock - clock speed for all ADC's. This is only set once for the first
+ * call to tiva_adc_initialize, otherwise the values are ignored.
+ * sample_rate - maximum sample rate of any ADC. This is only set once
+ * for the first call to tiva_adc_initialize, otherwise the values are
+ * ignored.
*
****************************************************************************/
-FAR struct adc_dev_s *tiva_adc_initialize(int adc_num);
+int tiva_adc_initialize(const char *devpath, struct tiva_adc_cfg_s *cfg,
+ uint32_t clock, uint8_t sample_rate);
/****************************************************************************
* Interfaces exported from the ADC driver
@@ -111,33 +228,460 @@ void tiva_adc_lock(FAR struct tiva_adc_s *priv, int sse);
void tiva_adc_unlock(FAR struct tiva_adc_s *priv, int sse);
+#endif /* CONFIG_ADC */
+
/****************************************************************************
- * Name: tiva_adc_getreg
+ * Library Function Prototypes
+ ****************************************************************************/
+
+/* Initialization routines **************************************************/
+
+/****************************************************************************
+ * Name: tiva_adc_one_time_init
*
* Description:
- * Read any 32-bit register using an absolute address.
+ * Perform one-time initialization of global ADC settings; clock frequency
+ * and sampling rate.
+ *
+ * Assumptions/Limitations:
+ * Peripheral must be powered before one-time initialization.
*
****************************************************************************/
-#ifdef CONFIG_TIVA_ADC_REGDEBUG
-uint32_t tiva_adc_getreg(FAR struct tiva_adc_s *priv, uintptr_t address);
-#else
-# define tiva_adc_getreg(handle,addr) getreg32(addr)
+void tiva_adc_one_time_init(uint32_t clock, uint8_t sample_rate);
+
+/****************************************************************************
+ * Name: tiva_adc_configure
+ *
+ * Description:
+ * Performs configuration of a single ADC, it's valid sample sequencers and
+ * available steps.
+ *
+ ****************************************************************************/
+
+void tiva_adc_configure(struct tiva_adc_cfg_s *cfg);
+
+/****************************************************************************
+ * Name: tiva_adc_sse_cfg
+ *
+ * Description:
+ * Configure the sample sequencer.
+ *
+ ****************************************************************************/
+
+void tiva_adc_sse_cfg(uint8_t adc, uint8_t sse,
+ struct tiva_adc_sse_cfg_s *ssecfg);
+
+/****************************************************************************
+ * Name: tiva_adc_step_cfg
+ *
+ * Description:
+ * Configures a sample sequencer step.
+ *
+ ****************************************************************************/
+
+void tiva_adc_step_cfg(struct tiva_adc_step_cfg_s *stepcfg);
+
+/****************************************************************************
+ * Name: tiva_adc_get_trigger
+ *
+ * Description:
+ * For a given adc, sse and step, get the AIN (channel) associated.
+ *
+ ****************************************************************************/
+
+uint8_t tiva_adc_get_trigger(uint8_t adc, uint8_t sse);
+
+/****************************************************************************
+ * Name: tiva_adc_get_ain
+ *
+ * Description:
+ * For a given adc, sse and step, get the AIN (channel) associated.
+ *
+ ****************************************************************************/
+
+uint8_t tiva_adc_get_ain(uint8_t adc, uint8_t sse, uint8_t step);
+
+/* IRQS *********************************************************************/
+
+/****************************************************************************
+ * Name: tiva_adc_irq_attach
+ *
+ * Description:
+ * Attach a custom interrupt handler.
+ *
+ ****************************************************************************/
+
+void tiva_adc_irq_attach(uint8_t adc, uint8_t sse, xcpt_t isr);
+
+/****************************************************************************
+ * Name: tiva_adc_irq_detach
+ *
+ * Description:
+ * detach an interrupt handler.
+ *
+ ****************************************************************************/
+
+void tiva_adc_irq_detach(uint8_t adc, uint8_t sse);
+
+/****************************************************************************
+ * Name: tiva_adc_getirq
+ *
+ * Description:
+ * Maps ADC and SSE value to the correct IRQ value.
+ *
+ ****************************************************************************/
+
+int tiva_adc_getirq(uint8_t adc, uint8_t sse);
+
+/* Common peripheral level **************************************************/
+
+/****************************************************************************
+ * Name: tiva_adc_enable
+ *
+ * Description:
+ * Toggles the operational state of the ADC peripheral
+ *
+ * Input Parameters:
+ * state - operation state
+ *
+ ****************************************************************************/
+
+int tiva_adc_enable(uint8_t adc, bool state);
+
+/****************************************************************************
+ * Name: tiva_adc_clock
+ *
+ * Description:
+ * Sets the ADC peripherals clock to the desired frequency.
+ *
+ * Input Parameters:
+ * freq - ADC clock value; dependent on platform:
+ *
+ * TM4C123 - Select either MOSC or PIOSC. Both result in 16 MHz operation,
+ * however the PIOSC allows the ADC to operate in deep sleep mode.
+ *
+ * TM4C129 - For the 129, there is still a selection between various internal
+ * clocks, however the output frequency is variable (16 MHz - 32 MHz); so it
+ * is much more intuitive to allow the clock variable be a frequency value.
+ *
+ ****************************************************************************/
+
+void tiva_adc_clock(uint32_t freq);
+
+/****************************************************************************
+ * Name: tiva_adc_vref
+ *
+ * Description:
+ * Sets the ADC peripherals clock to the desired frequency.
+ *
+ * Input Parameters:
+ * vref - ADC clock voltage reference source
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ARCH_CHIP_TM4C129
+void tiva_adc_vref(uint8_t vref);
#endif
+/* Peripheral (base) level **************************************************/
+
/****************************************************************************
- * Name: tiva_adc_putreg
+ * Name: tiva_adc_sample_rate
*
* Description:
- * Write to any 32-bit register using an absolute address.
+ * Sets the ADC sample rate as follows for each processor.
+ * TM4C123 - by maximum samples: 125 ksps, 250 ksps, 500 ksps or 1 Msps
+ * TM4C129 - by a divisor either being full, half, quarter or
+ * an eighth.
+ *
+ * Input Parameters:
+ * rate - ADC sample rate divisor
*
****************************************************************************/
-#ifdef CONFIG_TIVA_ADC_REGDEBUG
-void tiva_adc_putreg(FAR struct tiva_adc_s *priv, uintptr_t address,
- uint32_t regval);
-#else
-# define tiva_adc_putreg(handle,addr,val) putreg32(val,addr)
+void tiva_adc_sample_rate(uint8_t rate);
+
+/****************************************************************************
+ * Name: tiva_adc_proc_trig
+ *
+ * Description:
+ * Triggers the sample sequence to start it's conversion(s) and store them
+ * to the FIFO. This is only required when the trigger source is set to the
+ * processor.
+ *
+ * Input parameters:
+ * adc - which ADC peripherals' sample sequencers to trigger
+ * sse_mask - sample sequencer bitmask, each sse is 1 shifted by the sse
+ * number. e.g.
+ * SSE0 = 1 << 0
+ * SSE1 = 1 << 1
+ * SSE2 = 1 << 2
+ * SSE3 = 1 << 3
+ *
+ ****************************************************************************/
+
+void tiva_adc_proc_trig(uint8_t adc, uint8_t sse_mask);
+
+/****************************************************************************
+ * Name: tiva_adc_int_status
+ *
+ * Description:
+ * Returns raw interrupt status for the input ADC
+ *
+ * Input parameters:
+ * adc - which ADC peripherals' interrupt status to retrieve
+ *
+ ****************************************************************************/
+
+uint32_t tiva_adc_int_status(uint8_t adc);
+
+/* Sample Sequencer (SSE) level *********************************************/
+
+/****************************************************************************
+ * Name: tiva_adc_sse_enable
+ *
+ * Description:
+ * Sets the operation state of an ADC's sample sequencer (SSE). SSEs must
+ * be configured before being enabled.
+ *
+ * Input parameters:
+ * adc - peripheral state
+ * sse - sample sequencer
+ * state - sample sequencer enable/disable state
+ *
+ * Return value:
+ * Actual state of the ACTSS register.
+ *
+ ****************************************************************************/
+
+uint8_t tiva_adc_sse_enable(uint8_t adc, uint8_t sse, bool state);
+
+/****************************************************************************
+ * Name: tiva_adc_sse_trigger
+ *
+ * Description:
+ * Sets the trigger configuration for an ADC's sample sequencer (SSE).
+ * Possible triggers are the following:
+ * - Processor
+ * - PWMs, requires that one of the PWMnn_TRIG_CFG defines be OR'd
+ * into the trigger value.
+ * - Timers
+ * - GPIO (which GPIO is platform specific, consult the datasheet)
+ * - Always
+ * - !!UNSUPPORTED: Comparators
+ *
+ * Input parameters:
+ * adc - peripheral state
+ * sse - sample sequencer
+ * trigger - interrupt trigger
+ *
+ ****************************************************************************/
+
+void tiva_adc_sse_trigger(uint8_t adc, uint8_t sse, uint32_t trigger);
+
+/****************************************************************************
+ * Name: tiva_adc_sse_pwm_trig
+ *
+ * Description:
+ * Additional triggering configuration for PWM. Sets which PWM and which
+ * generator.
+ *
+ * Input parameters:
+ * adc - peripheral state
+ * sse - sample sequencer
+ * cfg - which PWM modulator and generator to use, use TIVA_ADC_PWM_TRIG
+ * to encode the value correctly
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_EXPERIMENTAL
+void tiva_adc_sse_pwm_trig(uint8_t adc, uint8_t sse, uint32_t cfg);
+#endif
+
+/****************************************************************************
+ * Name: tiva_adc_sse_int_enable
+ *
+ * Description:
+ * Sets the interrupt state of an ADC's sample sequencer (SSE). SSEs must
+ * be enabled before setting interrupt state.
+ *
+ * Input parameters:
+ * adc - peripheral state
+ * sse - sample sequencer
+ * state - sample sequencer enable/disable interrupt state
+ *
+ ****************************************************************************/
+
+void tiva_adc_sse_int_enable(uint8_t adc, uint8_t sse, bool state);
+
+/****************************************************************************
+ * Name: tiva_adc_sse_int_status
+ *
+ * Description:
+ * Returns interrupt status for the specificed SSE
+ *
+ * Input parameters:
+ * adc - which ADC peripherals' interrupt status to retrieve
+ * sse - which SSE interrupt status to retrieve
+ *
+ ****************************************************************************/
+
+bool tiva_adc_sse_int_status(uint8_t adc, uint8_t sse);
+
+/****************************************************************************
+ * Name: tiva_adc_sse_clear_int
+ *
+ * Description:
+ * Clears the interrupt bit for the SSE.
+ *
+ * Input parameters:
+ * adc - peripheral state
+ * sse - sample sequencer
+ * state - sample sequencer
+ *
+ ****************************************************************************/
+
+void tiva_adc_sse_clear_int(uint8_t adc, uint8_t sse);
+
+/****************************************************************************
+ * Name: tiva_adc_sse_data
+ *
+ * Description:
+ * Retrieves data from the FIFOs for all steps in the given sample sequencer.
+ * The input data buffer MUST be as large or larger than the sample sequencer.
+ * otherwise
+ *
+ * Input parameters:
+ * adc - peripheral state
+ * sse - sample sequencer
+ *
+ * Return value:
+ * number of steps read from FIFO.
+ *
+ ****************************************************************************/
+
+uint8_t tiva_adc_sse_data(uint8_t adc, uint8_t sse, int32_t *buf);
+
+/****************************************************************************
+ * Name: tiva_adc_sse_priority
+ *
+ * Description:
+ * Sets the priority configuration for an ADC's sample sequencer (SSE). The
+ * priority value ranges from 0 to 3, 0 being the highest priority, 3 being
+ * the lowest. There can be no duplicate values.
+ *
+ * Input parameters:
+ * adc - peripheral state
+ * sse - sample sequencer
+ * priority - conversion priority
+ *
+ ****************************************************************************/
+
+void tiva_adc_sse_priority(uint8_t adc, uint8_t sse, uint8_t priority);
+
+/****************************************************************************
+ * Name: tiva_adc_sse_register_chn
+ *
+ * Description:
+ * Registers an input channel to an SSE. Channels are registered according
+ * to the step and channel values stored in the channel struct. If the SSE
+ * already has a channel registered, it is overwritten by the new channel.
+ *
+ * *SSEMUX only supported on TM4C129 devices
+ *
+ * Input parameters:
+ * adc - peripheral state
+ * sse - sample sequencer
+ * chn - sample sequencer step
+ * ain - analog input pin
+ *
+ ****************************************************************************/
+
+void tiva_adc_sse_register_chn(uint8_t adc, uint8_t sse, uint8_t chn, uint32_t ain);
+
+/****************************************************************************
+ * Name: tiva_adc_sse_differential
+ *
+ * Description:
+ * Sets the differential capability for a SSE. !! UNSUPPORTED
+ *
+ * Input parameters:
+ * adc - peripheral state
+ * sse - sample sequencer
+ * chn - sample sequencer channel
+ * diff - differential configuration
+ *
+ ****************************************************************************/
+
+void tiva_adc_sse_differential(uint8_t adc, uint8_t sse, uint8_t chn, uint32_t diff);
+
+/****************************************************************************
+ * Name: tiva_adc_sse_sample_hold_time
+ *
+ * Description:
+ * Set the sample and hold time for this step.
+ *
+ * This is not available on all devices, however on devices that do not
+ * support this feature these reserved bits are ignored on write access.
+ *
+ * Input parameters:
+ * adc - peripheral state
+ * sse - sample sequencer
+ * chn - sample sequencer channel
+ * shold - sample and hold time
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_EXPERIMENTAL
+void tiva_adc_sse_sample_hold_time(uint8_t adc, uint8_t sse, uint8_t chn, uint32_t shold);
+#endif
+
+/****************************************************************************
+ * Name: tiva_adc_sse_step_cfg
+ *
+ * Description:
+ * Configures the given SSE step to one of the following options:
+ * -Temperature sensor select: this step is muxed to the internal
+ * temperature sensor.
+ * -Interrupt enabled select: this step causes the interrupt bit to
+ * be set and, if the MASK0 bit in ADC_IM register is set, the
+ * interrupt is promoted to the interrupt controller.
+ * -Sequence end select: This step is the last sequence to be sampled.
+ * This MUST be set somewhere in the SSE.
+ * -*Comparator/Differential select: The analog input is differentially
+ * sampled. The corresponding ADCSSMUXn nibble must be set to the pair
+ * number "i", where the paired inputs are "2i and 2i+1". Because the
+ * temperature sensor does not have a differential option, this bit must
+ * not be set when the TS3 bit is set.
+ *
+ * *Comparator/Differential functionality is unsupported and ignored.
+ *
+ * Input parameters:
+ * adc - peripheral state
+ * sse - sample sequencer
+ * chn - sample sequencer channel
+ * cfg - step configuration
+ *
+ ****************************************************************************/
+
+void tiva_adc_sse_step_cfg(uint8_t adc, uint8_t sse, uint8_t chn, uint8_t cfg);
+
+/****************************************************************************
+ * Name: tiva_adc_dump_reg_cfg
+ *
+ * Description:
+ * Dump all configured registers for the given ADC and SSE. This should
+ * only be used to verify that configuration routines were accurate.
+ *
+ * Input parameters:
+ * adc - peripheral state
+ * sse - sample sequencer
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_ANALOG
+void tiva_adc_dump_reg_cfg(uint8_t adc, uint8_t sse);
#endif
# undef EXTERN
diff --git a/nuttx/arch/arm/src/tiva/tiva_adclib.c b/nuttx/arch/arm/src/tiva/tiva_adclib.c
new file mode 100644
index 000000000..f003000ed
--- /dev/null
+++ b/nuttx/arch/arm/src/tiva/tiva_adclib.c
@@ -0,0 +1,1104 @@
+/****************************************************************************
+ * arch/arm/src/tiva/tiva_adclib.c
+ *
+ * Copyright (C) 2015 TRD2 Inc. All rights reserved.
+ * Author: Calvin Maguranis <calvin.maguranis@trd2inc.com>
+ *
+ * References:
+ *
+ * TM4C123GH6PM Series Data Sheet
+ * TI Tivaware driverlib ADC sample code.
+ *
+ * The Tivaware sample code has a BSD compatible license that requires this
+ * copyright notice:
+ *
+ * Copyright (c) 2005-2014 Texas Instruments Incorporated. All rights reserved.
+ * Software License Agreement
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This is part of revision 2.1.0.12573 of the Tiva Peripheral Driver Library.
+ *****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+#include <nuttx/arch.h>
+#include <nuttx/analog/adc.h>
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <debug.h>
+#include <assert.h>
+
+#include <arch/board/board.h>
+
+#include "up_arch.h"
+#include "up_internal.h"
+#include "tiva_gpio.h"
+#include "tiva_adc.h"
+#include "chip/tiva_adc.h"
+#include "chip/tiva_pinmap.h"
+
+#if defined (CONFIG_TIVA_ADC0) || defined (CONFIG_TIVA_ADC1)
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define CLOCK_CONFIG(div, src) \
+ ( ((((div) << ADC_CC_CLKDIV_SHIFT) & ADC_CC_CLKDIV_MASK) | \
+ ((src) & ADC_CC_CS_MASK)) & (ADC_CC_CLKDIV_MASK + ADC_CC_CS_MASK) )
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static uint8_t sse2irq[] =
+{
+#ifdef CONFIG_TIVA_ADC0
+ TIVA_IRQ_ADC0, TIVA_IRQ_ADC1, TIVA_IRQ_ADC2, TIVA_IRQ_ADC3
+#endif
+#ifdef CONFIG_TIVA_ADC1
+ , TIVA_IRQ_ADC1_0, TIVA_IRQ_ADC1_1, TIVA_IRQ_ADC1_2, TIVA_IRQ_ADC1_3
+#endif
+};
+
+static uint32_t ain2gpio[] =
+{
+#ifdef GPIO_ADC_AIN0
+ GPIO_ADC_AIN0
+#endif
+#ifdef GPIO_ADC_AIN1
+ , GPIO_ADC_AIN1
+#endif
+#ifdef GPIO_ADC_AIN2
+ , GPIO_ADC_AIN2
+#endif
+#ifdef GPIO_ADC_AIN3
+ , GPIO_ADC_AIN3
+#endif
+#ifdef GPIO_ADC_AIN4
+ , GPIO_ADC_AIN4
+#endif
+#ifdef GPIO_ADC_AIN5
+ , GPIO_ADC_AIN5
+#endif
+#ifdef GPIO_ADC_AIN6
+ , GPIO_ADC_AIN6
+#endif
+#ifdef GPIO_ADC_AIN7
+ , GPIO_ADC_AIN7
+#endif
+#ifdef GPIO_ADC_AIN8
+ , GPIO_ADC_AIN8
+#endif
+#ifdef GPIO_ADC_AIN9
+ , GPIO_ADC_AIN9
+#endif
+#ifdef GPIO_ADC_AIN10
+ , GPIO_ADC_AIN10
+#endif
+#ifdef GPIO_ADC_AIN11
+ , GPIO_ADC_AIN11
+#endif
+#ifdef GPIO_ADC_AIN12
+ , GPIO_ADC_AIN12
+#endif
+#ifdef GPIO_ADC_AIN13
+ , GPIO_ADC_AIN13
+#endif
+#ifdef GPIO_ADC_AIN14
+ , GPIO_ADC_AIN14
+#endif
+#ifdef GPIO_ADC_AIN15
+ , GPIO_ADC_AIN15
+#endif
+#ifdef GPIO_ADC_AIN16
+ , GPIO_ADC_AIN16
+#endif
+#ifdef GPIO_ADC_AIN17
+ , GPIO_ADC_AIN17
+#endif
+#ifdef GPIO_ADC_AIN18
+ , GPIO_ADC_AIN18
+#endif
+#ifdef GPIO_ADC_AIN19
+ , GPIO_ADC_AIN19
+#endif
+#ifdef GPIO_ADC_AIN20
+ , GPIO_ADC_AIN20
+#endif
+#ifdef GPIO_ADC_AIN21
+ , GPIO_ADC_AIN21
+#endif
+#ifdef GPIO_ADC_AIN22
+ , GPIO_ADC_AIN22
+#endif
+#ifdef GPIO_ADC_AIN23
+ , GPIO_ADC_AIN23
+#endif
+};
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: tiva_adc_one_time_init
+ *
+ * Description:
+ * Perform one-time initialization of global ADC settings; clock frequency
+ * and sampling rate.
+ *
+ * Assumptions/Limitations:
+ * Peripheral must be powered before one-time initialization.
+ *
+ ****************************************************************************/
+
+void tiva_adc_one_time_init(uint32_t clock, uint8_t sample_rate)
+{
+ static bool one_time_init = false;
+
+#ifdef CONFIG_DEBUG_ANALOG
+ avdbg("setting clock=%d MHz sample rate=%d\n",
+ clock, sample_rate);
+#endif
+
+ /* Have the common peripheral properties already been initialized? If yes,
+ * continue.
+ */
+
+ if (one_time_init == false)
+ {
+ avdbg("performing ADC one-time initialization...\n");
+ /* set clock */
+
+ tiva_adc_clock(clock);
+
+ /* set sampling rate */
+
+ tiva_adc_sample_rate(sample_rate);
+
+#ifdef CONFIG_ARCH_CHIP_TM4C129
+ /* voltage reference */
+
+ tiva_adc_vref();
+#endif
+ one_time_init = true;
+ }
+#ifdef CONFIG_DEBUG_ANALOG
+ else
+ {
+ avdbg("one time initialization previously completed\n");
+ }
+#endif
+}
+
+/****************************************************************************
+ * Name: tiva_adc_configure
+ *
+ * Description:
+ * Performs configuration of a single ADC, it's valid sample sequencers and
+ * available steps.
+ *
+ ****************************************************************************/
+
+void tiva_adc_configure(struct tiva_adc_cfg_s *cfg)
+{
+ uint8_t s;
+ uint8_t c;
+
+ avdbg("configure ADC%d...\n", cfg->adc);
+
+ /* Configure each SSE */
+
+ for (s=0; s<4; ++s)
+ {
+ if (cfg->sse[s])
+ {
+ tiva_adc_sse_cfg(cfg->adc, s, &cfg->ssecfg[s]);
+ }
+#ifdef CONFIG_DEBUG_ANALOG
+ else
+ {
+ avdbg("ADC%d SSE%d has no configuration\n", cfg->adc, s);
+ }
+#endif
+ }
+
+ /* Configure each step */
+
+ for (c=0; c<cfg->steps; ++c)
+ {
+ tiva_adc_step_cfg(&cfg->stepcfg[c]);
+ }
+
+#ifdef CONFIG_DEBUG_ANALOG
+ tiva_adc_dump_reg_cfg(cfg->adc, 0);
+#endif
+}
+
+/****************************************************************************
+ * Name: tiva_adc_sse_cfg
+ *
+ * Description:
+ * Configure the sample sequencer.
+ *
+ ****************************************************************************/
+
+void tiva_adc_sse_cfg(uint8_t adc, uint8_t sse,
+ struct tiva_adc_sse_cfg_s *ssecfg)
+{
+ avdbg("configure ADC%d SSE%d...\n", adc, sse);
+#ifdef CONFIG_DEBUG_ANALOG
+ avdbg("priority=%d trigger=%d...\n", ssecfg->priority, ssecfg->trigger);
+#endif
+
+ uint8_t priority = ssecfg->priority;
+ uint8_t trigger = ssecfg->trigger;
+
+ /* Ensure SSE is disabled before configuring */
+
+ tiva_adc_sse_enable(adc, sse, false);
+
+ /* Set conversion priority and trigger source for all steps in the SSE */
+
+ tiva_adc_sse_priority(adc, sse, priority);
+ tiva_adc_sse_trigger(adc, sse, trigger);
+}
+
+/****************************************************************************
+ * Name: tiva_adc_step_cfg
+ *
+ * Description:
+ * Configures a sample sequencer step.
+ *
+ ****************************************************************************/
+
+void tiva_adc_step_cfg(struct tiva_adc_step_cfg_s *stepcfg)
+{
+#ifdef CONFIG_DEBUG_ANALOG
+ avdbg(" shold=0x%02x flags=0x%02x ain=%d...\n",
+ stepcfg->shold, stepcfg->flags, stepcfg->ain);
+#endif
+
+ uint8_t adc = stepcfg->adc;
+ uint8_t sse = stepcfg->sse;
+ uint8_t step = stepcfg->step;
+#ifdef CONFIG_EXPERIMENTAL
+ uint8_t shold = stepcfg->shold;
+#endif
+ uint8_t flags = stepcfg->flags;
+ uint8_t ain = stepcfg->ain;
+ uint32_t gpio = ain2gpio[stepcfg->ain];
+
+ avdbg("configure ADC%d SSE%d STEP%d...\n", adc, sse, step);
+
+ /* Configure the AIN GPIO for analog input if not flagged to be muxed to
+ * the internal temperature sensor
+ */
+
+ if ((flags & TIVA_ADC_FLAG_TS) != TIVA_ADC_FLAG_TS)
+ {
+ tiva_configgpio(gpio);
+ }
+
+ /* Register, set sample/hold time and configure the step */
+
+ tiva_adc_sse_register_chn(adc, sse, step, ain);
+ tiva_adc_sse_differential(adc, sse, step, 0); /* TODO: update when differential
+ * support is added. */
+#ifdef CONFIG_EXPERIMENTAL
+ tiva_adc_sse_sample_hold_time(adc, sse, step, shold);
+#endif
+ tiva_adc_sse_step_cfg(adc, sse, step, flags);
+}
+
+/****************************************************************************
+ * Name: tiva_adc_get_trigger
+ *
+ * Description:
+ * For a given adc, sse and step, get the AIN (channel) associated.
+ *
+ ****************************************************************************/
+
+uint8_t tiva_adc_get_trigger(uint8_t adc, uint8_t sse)
+{
+ uintptr_t emuxaddr = TIVA_ADC_EMUX(adc);
+ uint32_t emux = getreg32(emuxaddr) & ADC_EMUX_MASK(sse);
+ return (emux >> ADC_EMUX_SHIFT(sse));
+}
+
+/****************************************************************************
+ * Name: tiva_adc_get_ain
+ *
+ * Description:
+ * For a given adc, sse and step, get the AIN (channel) associated.
+ *
+ ****************************************************************************/
+
+uint8_t tiva_adc_get_ain(uint8_t adc, uint8_t sse, uint8_t step)
+{
+ uintptr_t ssmuxaddr = TIVA_ADC_BASE(adc)+TIVA_ADC_SSMUX(sse);
+ uint32_t ssmux = getreg32(ssmuxaddr) & ADC_SSMUX_MUX_MASK(step);
+ return (ssmux >> ADC_SSMUX_MUX_SHIFT(step));
+}
+
+/* IRQS *********************************************************************/
+
+/****************************************************************************
+ * Name: tiva_adc_irq_attach
+ *
+ * Description:
+ * Attach a custom interrupt handler.
+ *
+ ****************************************************************************/
+
+void tiva_adc_irq_attach(uint8_t adc, uint8_t sse, xcpt_t isr)
+{
+
+ uint32_t ret = 0;
+ int irq = sse2irq[SSE_IDX(adc, sse)];
+
+#ifdef CONFIG_DEBUG_ANALOG
+ avdbg("assigning ISR=0x%p to ADC%d SSE%d IRQ=0x%02x...\n",
+ isr, adc, sse, irq);
+#endif
+
+ ret = irq_attach(irq, isr);
+ if (ret < 0)
+ {
+ adbg("ERROR: Failed to attach IRQ %d: %d\n", irq, ret);
+ return;
+ }
+
+ up_enable_irq(irq);
+}
+
+/****************************************************************************
+ * Name: tiva_adc_irq_detach
+ *
+ * Description:
+ * detach an interrupt handler.
+ *
+ ****************************************************************************/
+
+void tiva_adc_irq_detach(uint8_t adc, uint8_t sse)
+{
+ uint32_t ret = 0;
+ int irq = sse2irq[SSE_IDX(adc, sse)];
+
+ /* Disable ADC interrupts at the level of the AIC */
+
+ up_disable_irq(irq);
+
+ /* Then detach the ADC interrupt handler. */
+
+ ret = irq_detach(irq);
+ if (ret < 0)
+ {
+ adbg("ERROR: Failed to detach IRQ %d: %d\n", irq, ret);
+ return;
+ }
+}
+
+/****************************************************************************
+ * Name: tiva_adc_getirq
+ *
+ * Description:
+ * Maps ADC and SSE value to the correct IRQ value.
+ *
+ ****************************************************************************/
+
+int tiva_adc_getirq(uint8_t adc, uint8_t sse)
+{
+ return sse2irq[SSE_IDX(adc, sse)];
+}
+
+/* Peripheral (base) level **************************************************/
+
+/****************************************************************************
+ * Name: tiva_adc_enable
+ *
+ * Description:
+ * Toggles the operational state of the ADC peripheral
+ *
+ * Input Parameters:
+ * state - operation state
+ *
+ ****************************************************************************/
+
+int tiva_adc_enable(uint8_t adc, bool state)
+{
+ if (state == true)
+ {
+ /* Enable clocking to the ADC peripheral */
+
+#ifdef TIVA_SYSCON_RCGCADC
+ modifyreg32(TIVA_SYSCON_RCGCADC, 0, 1 << adc);
+#else
+ modifyreg32(TIVA_SYSCON_RCGC0, 0, SYSCON_RCGC0_ADC0);
+#endif
+ return OK;
+ }
+ else if (state == false)
+ {
+ /* Disable clocking to the ADC peripheral */
+
+#ifdef TIVA_SYSCON_RCGCADC
+ modifyreg32(TIVA_SYSCON_RCGCADC, 1 << adc, 0);
+#else
+ modifyreg32(TIVA_SYSCON_RCGC0, SYSCON_RCGC0_ADC0, 0);
+#endif
+ return OK;
+ }
+
+ /* ERROR! */
+
+ return -1;
+}
+
+/****************************************************************************
+ * Name: tiva_adc_clock
+ *
+ * Description:
+ * Sets the ADC peripherals clock to the desired frequency.
+ *
+ * Input Parameters:
+ * freq - ADC clock value; dependent on platform:
+ *
+ * TM4C123 - Select either MOSC or PIOSC. Both result in 16 MHz operation,
+ * however the PIOSC allows the ADC to operate in deep sleep mode.
+ *
+ * TM4C129 - For the 129, there is still a selection between various internal
+ * clocks, however the output frequency is variable (16 MHz - 32 MHz); so it
+ * is much more intuitive to allow the clock variable be a frequency value.
+ *
+ ****************************************************************************/
+
+void tiva_adc_clock(uint32_t freq)
+{
+#if defined(CONFIG_ARCH_CHIP_TM4C123)
+ /* For the TM4C123, the ADC clock source does not affect the frequency, it
+ * runs at 16 MHz regardless. You end up selecting between the MOSC (default)
+ * or the PIOSC. The PIOSC allows the ADC to operate even in deep sleep mode.
+ * Since this is the case, the clock value for the TM4C123 is always 16 MHz
+ */
+
+ uintptr_t ccreg = (TIVA_ADC0_BASE + TIVA_ADC_CC_OFFSET);
+ modifyreg32(ccreg, ADC_CC_CS_MASK, (ADC_CC_CS_PIOSC & ADC_CC_CS_MASK));
+
+#elif defined (CONFIG_ARCH_CHIP_TM4C129)
+ /* check clock bounds and specific match cases */
+
+ uint32_t clk_src = 0;
+ uint32_t div = 0;
+ if (freq > TIVA_ADC_CLOCK_MAX)
+ {
+ clk_src = ADC_CC_CS_SYSPLL;
+ div = (BOARD_FVCO_FREQUENCY / TIVA_ADC_CLOCK_MAX);
+ }
+ else if (freq < TIVA_ADC_CLOCK_MIN)
+ {
+ clk_src = ADC_CC_CS_PIOSC;
+ div = 1;
+ }
+ else if (freq == XTAL_FREQUENCY)
+ {
+ clk_src = ADC_CC_CS_MOSC;
+ div = 1;
+ }
+ else
+ {
+ clk_src = ADC_CC_CS_SYSPLL;
+ div = (BOARD_FVCO_FREQUENCY / freq);
+ }
+
+ uintptr_t ccreg = (TIVA_ADC0_BASE + TIVA_ADC_CC_OFFSET);
+ modifyreg32(ccreg, ADC_CC_CLKDIV_MASK, CLOCK_CONFIG(div, clk_src));
+#else
+# error Unsupported architecture reported
+#endif
+}
+
+/****************************************************************************
+ * Name: tiva_adc_vref
+ *
+ * Description:
+ * Sets the ADC peripherals clock to the desired frequency.
+ *
+ * Input Parameters:
+ * vref - ADC clock voltage reference source
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ARCH_CHIP_TM4C129
+void tiva_adc_vref(uint8_t vref)
+{
+ uintptr_t ctlreg = (TIVA_ADC0_BASE + TIVA_ADC_CTL_OFFSET);
+ modifyreg32(ctlreg, ADC_CTL_VREF_MASK, (vref & ADC_CTL_VREF_MASK));
+}
+#endif
+
+/****************************************************************************
+ * Name: tiva_adc_sample_rate
+ *
+ * Description:
+ * Sets the ADC sample rate as follows for each processor.
+ * TM4C123 - by maximum samples: 125 ksps, 250 ksps, 500 ksps or 1 Msps
+ * TM4C129 - by a divisor either being full, half, quarter or
+ * an eighth.
+ *
+ * Input Parameters:
+ * rate - ADC sample rate divisor
+ *
+ ****************************************************************************/
+
+void tiva_adc_sample_rate(uint8_t rate)
+{
+ uintptr_t pcreg = (TIVA_ADC0_BASE + TIVA_ADC_PC_OFFSET);
+
+ /* NOTE: ADC_PC_SR_MASK is intended for use with the TM4C123, the
+ * alternative is ADC_PC_MCR_MASK for the TM4C129. However both masks
+ * mask off the first 4 bits (0xF) so there is no need to distinguish
+ * between the two.
+ */
+
+ modifyreg32(pcreg, ADC_PC_SR_MASK, (rate & ADC_PC_SR_MASK));
+}
+
+/****************************************************************************
+ * Name: tiva_adc_proc_trig
+ *
+ * Description:
+ * Triggers the sample sequence to start it's conversion(s) and store them
+ * to the FIFO. This is only required when the trigger source is set to the
+ * processor.
+ *
+ * Input parameters:
+ * adc - which ADC peripherals' sample sequencers to trigger
+ * sse_mask - sample sequencer bitmask, each sse is 1 shifted by the sse
+ * number. e.g.
+ * SSE0 = 1 << 0
+ * SSE1 = 1 << 1
+ * SSE2 = 1 << 2
+ * SSE3 = 1 << 3
+ *
+ ****************************************************************************/
+
+void tiva_adc_proc_trig(uint8_t adc, uint8_t sse_mask)
+{
+ uintptr_t pssireg = TIVA_ADC_PSSI(adc);
+ putreg32((sse_mask & ADC_PSSI_TRIG_MASK), pssireg);
+#ifdef CONFIG_TIVA_ADC_SYNC
+# warning CONFIG_TIVA_ADC_SYNC unsupported at this time.
+#endif
+}
+
+/****************************************************************************
+ * Name: tiva_adc_int_status
+ *
+ * Description:
+ * Returns raw interrupt status for the input ADC
+ *
+ * Input parameters:
+ * adc - which ADC peripherals' interrupt status to retrieve
+ *
+ ****************************************************************************/
+
+uint32_t tiva_adc_int_status(uint8_t adc)
+{
+ uint32_t ris = getreg32(TIVA_ADC_RIS(adc));
+ return ris;
+}
+
+/* Sample sequencer (SSE) functions *****************************************/
+
+/****************************************************************************
+ * Name: tiva_adc_sse_enable
+ *
+ * Description:
+ * Sets the operation state of an ADC's sample sequencer (SSE). SSEs must
+ * be configured before being enabled.
+ *
+ * Input parameters:
+ * adc - peripheral state
+ * sse - sample sequencer
+ * state - sample sequencer enable/disable state
+ *
+ * Return value:
+ * Actual state of the ACTSS register.
+ *
+ ****************************************************************************/
+
+uint8_t tiva_adc_sse_enable(uint8_t adc, uint8_t sse, bool state)
+{
+ avdbg("ADC%d SSE%d=%01d\n", adc, sse, state);
+
+ uintptr_t actssreg = TIVA_ADC_ACTSS(adc);
+ if (state == true)
+ {
+ modifyreg32(actssreg, 0, (1 << sse));
+ }
+ else
+ {
+ modifyreg32(actssreg, (1 << sse), 0);
+ }
+
+ return (getreg32(actssreg) & 0xF);
+}
+
+/****************************************************************************
+ * Name: tiva_adc_sse_trigger
+ *
+ * Description:
+ * Sets the trigger configuration for an ADC's sample sequencer (SSE).
+ * Possible triggers are the following:
+ * - Processor
+ * - PWMs, requires that one of the PWMnn_TRIG_CFG defines be OR'd
+ * into the trigger value.
+ * - Timers
+ * - GPIO (which GPIO is platform specific, consult the datasheet)
+ * - Always
+ * - !!UNSUPPORTED: Comparators
+ *
+ * Input parameters:
+ * adc - peripheral state
+ * sse - sample sequencer
+ * trigger - interrupt trigger
+ *
+ ****************************************************************************/
+
+void tiva_adc_sse_trigger(uint8_t adc, uint8_t sse, uint32_t trigger)
+{
+ uintptr_t emuxreg = (TIVA_ADC_EMUX(adc));
+ uint32_t trig = ((trigger << ADC_EMUX_SHIFT(sse)) & ADC_EMUX_MASK(sse));
+ modifyreg32(emuxreg, ADC_EMUX_MASK(sse), trig);
+
+ /* NOTE: PWM triggering needs an additional register to be set (ADC_TSSEL)
+ * A platform specific IOCTL command is provided to configure the triggering.
+ */
+}
+
+/****************************************************************************
+ * Name: tiva_adc_sse_pwm_trig
+ *
+ * Description:
+ * Additional triggering configuration for PWM. Sets which PWM and which
+ * generator.
+ *
+ * Input parameters:
+ * adc - peripheral state
+ * sse - sample sequencer
+ * cfg - which PWM modulator and generator to use, use TIVA_ADC_PWM_TRIG
+ * to encode the value correctly
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_EXPERIMENTAL
+void tiva_adc_sse_pwm_trig(uint8_t adc, uint8_t sse, uint32_t cfg)
+{
+ /* PWM triggering needs an additional register to be set (ADC_TSSEL) */
+
+ uintptr_t tsselreg = TIVA_ADC_TSSEL(adc);
+
+ modifyreg32(tsselreg, ADC_TSSEL_PS_MASK(see), cfg);
+}
+#endif
+
+/****************************************************************************
+ * Name: tiva_adc_sse_int_enable
+ *
+ * Description:
+ * Sets the interrupt state of an ADC's sample sequencer (SSE). SSEs must
+ * be enabled before setting interrupt state.
+ *
+ * Input parameters:
+ * adc - peripheral state
+ * sse - sample sequencer
+ * state - sample sequencer enable/disable interrupt state
+ *
+ ****************************************************************************/
+
+void tiva_adc_sse_int_enable(uint8_t adc, uint8_t sse, bool state)
+{
+ irqstate_t flags;
+ uintptr_t imreg = TIVA_ADC_IM(adc);
+ int irq = tiva_adc_getirq(adc, sse);
+
+ flags = irqsave();
+ up_disable_irq(irq);
+
+ tiva_adc_sse_clear_int(adc, sse);
+
+ if (state == true)
+ {
+ modifyreg32(imreg, 0, (1 << sse));
+ }
+ else
+ {
+ modifyreg32(imreg, (1 << sse), 0);
+ }
+
+ up_enable_irq(irq);
+ irqrestore(flags);
+}
+
+/****************************************************************************
+ * Name: tiva_adc_sse_int_status
+ *
+ * Description:
+ * Returns interrupt status for the specificed SSE
+ *
+ * Input parameters:
+ * adc - which ADC peripherals' interrupt status to retrieve
+ * sse - which SSE interrupt status to retrieve
+ *
+ ****************************************************************************/
+
+bool tiva_adc_sse_int_status(uint8_t adc, uint8_t sse)
+{
+ uint32_t intstat = tiva_adc_int_status(adc);
+ uint32_t sseintstat = intstat & (1 << sse);
+ return sseintstat > 0 ? true : false;
+}
+
+/****************************************************************************
+ * Name: tiva_adc_sse_clear_int
+ *
+ * Description:
+ * Clears the interrupt bit for the SSE.
+ *
+ * Input parameters:
+ * adc - peripheral state
+ * sse - sample sequencer
+ * state - sample sequencer
+ *
+ ****************************************************************************/
+
+void tiva_adc_sse_clear_int(uint8_t adc, uint8_t sse)
+{
+ uintptr_t iscreg = TIVA_ADC_ISC(adc);
+ modifyreg32(iscreg, 0, (1 << sse));
+}
+
+/****************************************************************************
+ * Name: tiva_adc_sse_data
+ *
+ * Description:
+ * Retrieves data from the FIFOs for all steps in the given sample sequencer.
+ * The input data buffer MUST be as large or larger than the sample sequencer.
+ * otherwise
+ *
+ * Input parameters:
+ * adc - peripheral state
+ * sse - sample sequencer
+ *
+ * Return value:
+ * number of steps read from FIFO.
+ *
+ ****************************************************************************/
+
+uint8_t tiva_adc_sse_data(uint8_t adc, uint8_t sse, int32_t *buf)
+{
+ uint32_t ssfstatreg = getreg32(TIVA_ADC_BASE(adc) + TIVA_ADC_SSFSTAT(sse));
+ uint8_t fifo_count = 0;
+
+ /* Read samples from the FIFO until it is empty */
+
+ while (!(ssfstatreg & ADC_SSFSTAT_EMPTY) && fifo_count < 8)
+ {
+ /* Read the FIFO and copy it to the destination */
+
+ buf[fifo_count] = getreg32(TIVA_ADC_BASE(adc) + TIVA_ADC_SSFIFO(sse));
+ fifo_count++;
+
+ /* refresh fifo status register state */
+
+ ssfstatreg = getreg32(TIVA_ADC_BASE(adc) + TIVA_ADC_SSFSTAT(sse));
+ }
+
+ avdbg("fifo=%d\n", fifo_count);
+
+ return fifo_count;
+}
+
+/****************************************************************************
+ * Name: tiva_adc_sse_priority
+ *
+ * Description:
+ * Sets the priority configuration for an ADC's sample sequencer (SSE). The
+ * priority value ranges from 0 to 3, 0 being the highest priority, 3 being
+ * the lowest. There can be no duplicate values.
+ *
+ * Input parameters:
+ * adc - peripheral state
+ * sse - sample sequencer
+ * priority - conversion priority
+ *
+ ****************************************************************************/
+
+void tiva_adc_sse_priority(uint8_t adc, uint8_t sse, uint8_t priority)
+{
+ uintptr_t ssprireg = TIVA_ADC_SSPRI(adc);
+ uint32_t sspri = 0;
+
+ sspri = (priority << ADC_SSPRI_SHIFT(sse)) & ADC_SSPRI_MASK(sse);
+ modifyreg32(ssprireg, ADC_SSPRI_MASK(sse), sspri);
+}
+
+/****************************************************************************
+ * Name: tiva_adc_sse_register_chn
+ *
+ * Description:
+ * Registers an input channel to an SSE. Channels are registered according
+ * to the step and channel values stored in the channel struct. If the SSE
+ * already has a channel registered, it is overwritten by the new channel.
+ *
+ * *SSEMUX only supported on TM4C129 devices
+ *
+ * Input parameters:
+ * adc - peripheral state
+ * sse - sample sequencer
+ * chn - sample sequencer step
+ * ain - analog input pin
+ *
+ ****************************************************************************/
+
+void tiva_adc_sse_register_chn(uint8_t adc, uint8_t sse, uint8_t chn,
+ uint32_t ain)
+{
+ /* Configure SSE mux (SSMUX) with step number */
+
+ uintptr_t ssmuxreg = (TIVA_ADC_BASE(adc) + TIVA_ADC_SSMUX(sse));
+ uint32_t step = 0;
+
+ step = ((ain << ADC_SSMUX_MUX_SHIFT(chn)) & ADC_SSMUX_MUX_MASK(chn));
+ modifyreg32(ssmuxreg, ADC_SSMUX_MUX_MASK(chn), step);
+
+#ifdef CONFIG_ARCH_CHIP_TM4C129
+ /* Configure SSE extended mux (SSEMUX) with step number and configuration */
+
+ ssmuxreg = (TIVA_ADC_BASE(adc) + TIVA_ADC_SSEMUX(sse));
+ step = ((1 << ADC_SSEMUX_MUX_SHIFT(chn)) & ADC_SSEMUX_MUX_MASK(chn));
+ modifyreg32(ssmuxreg, ADC_SSEMUX_MUX_MASK(chn), step);
+#endif
+}
+
+/****************************************************************************
+ * Name: tiva_adc_sse_differential
+ *
+ * Description:
+ * Sets the differential capability for a SSE. !! UNSUPPORTED
+ *
+ * Input parameters:
+ * adc - peripheral state
+ * sse - sample sequencer
+ * chn - sample sequencer channel
+ * diff - differential configuration
+ *
+ ****************************************************************************/
+
+void tiva_adc_sse_differential(uint8_t adc, uint8_t sse, uint8_t chn, uint32_t diff)
+{
+#ifdef CONFIG_TIVA_ADC_DIFFERENTIAL
+# error CONFIG_TIVA_ADC_DIFFERENTIAL unsupported!!
+#else
+ /* for now, ensure the FIFO is used and differential sampling is disabled */
+
+ uintptr_t ssopreg = (TIVA_ADC_BASE(adc) + TIVA_ADC_SSOP(sse));
+ uint32_t sdcopcfg = (1 << chn);
+ modifyreg32(ssopreg, sdcopcfg, 0);
+#endif
+}
+
+/****************************************************************************
+ * Name: tiva_adc_sse_sample_hold_time
+ *
+ * Description:
+ * Set the sample and hold time for this step.
+ *
+ * This is not available on all devices, however on devices that do not
+ * support this feature these reserved bits are ignored on write access.
+ *
+ * Input parameters:
+ * adc - peripheral state
+ * sse - sample sequencer
+ * chn - sample sequencer channel
+ * shold - sample and hold time
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_EXPERIMENTAL
+void tiva_adc_sse_sample_hold_time(uint8_t adc, uint8_t sse,
+ uint8_t chn, uint32_t shold)
+{
+ uintptr_t sstshreg = (TIVA_ADC_BASE(adc) + TIVA_ADC_SSTSH(sse));
+ modifyreg32(sstshreg, ADC_SSTSH_MASK(sse), (shold << ADC_SSTSH_SHIFT(sse)));
+}
+#endif
+
+/****************************************************************************
+ * Name: tiva_adc_sse_step_cfg
+ *
+ * Description:
+ * Configures the given SSE step to one of the following options:
+ * -Temperature sensor select: this step is muxed to the internal
+ * temperature sensor.
+ * -Interrupt enabled select: this step causes the interrupt bit to
+ * be set and, if the MASK0 bit in ADC_IM register is set, the
+ * interrupt is promoted to the interrupt controller.
+ * -Sequence end select: This step is the last sequence to be sampled.
+ * This MUST be set somewhere in the SSE.
+ * -*Comparator/Differential select: The analog input is differentially
+ * sampled. The corresponding ADCSSMUXn nibble must be set to the pair
+ * number "i", where the paired inputs are "2i and 2i+1". Because the
+ * temperature sensor does not have a differential option, this bit must
+ * not be set when the TS3 bit is set.
+ *
+ * *Comparator/Differential functionality is unsupported and ignored.
+ *
+ * Input parameters:
+ * adc - peripheral state
+ * sse - sample sequencer
+ * chn - sample sequencer channel
+ * cfg - step configuration
+ *
+ ****************************************************************************/
+
+void tiva_adc_sse_step_cfg(uint8_t adc, uint8_t sse, uint8_t chn, uint8_t cfg)
+{
+ uintptr_t ssctlreg = (TIVA_ADC_BASE(adc) + TIVA_ADC_SSCTL(sse));
+ uint32_t ctlcfg = cfg << ADC_SSCTL_SHIFT(chn) & ADC_SSCTL_MASK(chn);
+ modifyreg32(ssctlreg, ADC_SSCTL_MASK(chn), ctlcfg);
+}
+
+/****************************************************************************
+ * Name: tiva_adc_dump_reg_cfg
+ *
+ * Description:
+ * Dump all configured registers for the given ADC and SSE. This should
+ * only be used to verify that configuration routines were accurate.
+ *
+ * Input parameters:
+ * adc - peripheral state
+ * sse - sample sequencer
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_ANALOG
+void tiva_adc_dump_reg_cfg(uint8_t adc, uint8_t sse)
+{
+ /* one-time initialization */
+
+ uintptr_t ccreg = (TIVA_ADC0_BASE + TIVA_ADC_CC_OFFSET); /* Clock */
+ uintptr_t pcreg = (TIVA_ADC0_BASE + TIVA_ADC_PC_OFFSET); /* Sample rate */
+
+ /* SSE cfg */
+
+ uintptr_t actssreg = TIVA_ADC_ACTSS(adc); /* SSE enable state */
+ uintptr_t ssprireg = TIVA_ADC_SSPRI(adc); /* SSE priority */
+ uintptr_t emuxreg = TIVA_ADC_EMUX(adc); /* SSE trigger */
+
+ /* step cfg */
+
+ uintptr_t ssmuxreg = (TIVA_ADC_BASE(adc) + TIVA_ADC_SSMUX(sse)); /* step registration */
+#ifdef CONFIG_ARCH_CHIP_TM4C129
+ uintptr_t ssemuxreg = (TIVA_ADC_BASE(adc) + TIVA_ADC_SSEMUX(sse)); /* extended mux registration */
+#endif
+ uintptr_t ssopreg = (TIVA_ADC_BASE(adc) + TIVA_ADC_SSOP(sse)); /* differential status */
+#ifdef CONFIG_EXPERIMENTAL
+ uintptr_t sstshreg = (TIVA_ADC_BASE(adc) + TIVA_ADC_SSTSH(sse)); /* sample and hold time */
+#endif
+ uintptr_t ssctlreg = (TIVA_ADC_BASE(adc) + TIVA_ADC_SSCTL(sse)); /* step configuration */
+
+ /* Get register contents */
+
+ uint32_t cc = getreg32(ccreg);
+ uint32_t pc = getreg32(pcreg);
+
+ /* SSE cfg */
+
+ uint32_t actss = getreg32(actssreg);
+ uint32_t sspri = getreg32(ssprireg);
+ uint32_t emux = getreg32(emuxreg);
+
+ /* step cfg */
+
+ uint32_t ssmux = getreg32(ssmuxreg);
+#ifdef CONFIG_ARCH_CHIP_TM4C129
+ uint32_t ssemux = getreg32(ssemuxreg);
+#endif
+ uint32_t ssop = getreg32(ssopreg);
+#ifdef CONFIG_EXPERIMENTAL
+ uint32_t sstsh = getreg32(sstshreg);
+#endif
+ uint32_t ssctl = getreg32(ssctlreg);
+
+ /* Dump register contents */
+
+ avdbg("CC [0x%08x]=0x%08x\n", ccreg, cc);
+ avdbg("PC [0x%08x]=0x%08x\n", pcreg, pc);
+ avdbg("ACTSS [0x%08x]=0x%08x\n", actssreg, actss);
+ avdbg("SSPRI [0x%08x]=0x%08x\n", ssprireg, sspri);
+ avdbg("EMUX [0x%08x]=0x%08x\n", emuxreg, emux);
+ avdbg("SSMUX [0x%08x]=0x%08x\n", ssmuxreg, ssmux);
+#ifdef CONFIG_ARCH_CHIP_TM4C129
+ avdbg("SSEMUX [0x%08x]=0x%08x\n", ssemuxreg, ssemux);
+#endif
+ avdbg("SSOP [0x%08x]=0x%08x\n", ssopreg, ssop);
+#ifdef CONFIG_EXPERIMENTAL
+ avdbg("SSTSH [0x%08x]=0x%08x\n", sstshreg, sstsh);
+#endif
+ avdbg("SSCTL [0x%08x]=0x%08x\n", ssctlreg, ssctl);
+
+}
+#endif /* CONFIG_DEBUG_ANALOG */
+#endif /* CONFIG_TIVA_ADC0 || CONFIG_TIVA_ADC1 */
diff --git a/nuttx/arch/arm/src/tiva/tiva_adclow.c b/nuttx/arch/arm/src/tiva/tiva_adclow.c
new file mode 100644
index 000000000..ede07693b
--- /dev/null
+++ b/nuttx/arch/arm/src/tiva/tiva_adclow.c
@@ -0,0 +1,1030 @@
+/****************************************************************************
+ * arch/arm/src/tiva/tiva_adclow.c
+ *
+ * Copyright (C) 2015 TRD2 Inc. All rights reserved.
+ * Author: Calvin Maguranis <calvin.maguranis@trd2inc.com>
+ *
+ * References:
+ *
+ * TM4C123GH6PM Series Data Sheet
+ * TI Tivaware driverlib ADC sample code.
+ *
+ * The Tivaware sample code has a BSD compatible license that requires this
+ * copyright notice:
+ *
+ * Copyright (c) 2005-2014 Texas Instruments Incorporated. All rights reserved.
+ * Software License Agreement
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This is part of revision 2.1.0.12573 of the Tiva Peripheral Driver Library.
+ *****************************************************************************/
+
+/* Keep in mind that for every step there should be another entry in the
+ * CONFIG_ADC_FIFOSIZE value.
+ * e.g. if there are 12 steps in use; CONFIG_ADC_FIFOSIZE = 12+1 = 13
+ * if there are 3 steps in use; CONFIG_ADC_FIFOSIZE = 3+1 = 4
+ */
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/arch.h>
+#include <nuttx/wqueue.h>
+#include <nuttx/analog/adc.h>
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <semaphore.h>
+#include <errno.h>
+#include <debug.h>
+#include <assert.h>
+
+#include <arch/board/board.h>
+
+#include "up_arch.h"
+#include "up_internal.h"
+#include "tiva_gpio.h"
+#include "tiva_adc.h"
+#include "chip/tiva_adc.h"
+#include "chip/tiva_pinmap.h"
+#include "chip/tiva_syscontrol.h"
+
+#if defined (CONFIG_TIVA_ADC) && defined (CONFIG_ADC)
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Configuration ************************************************************/
+
+#ifndef CONFIG_TIVA_ADC_CLOCK
+# define CONFIG_TIVA_ADC_CLOCK TIVA_ADC_CLOCK_MIN
+#endif
+
+#ifdef CONFIG_TIVA_ADC_VREF
+# ifndef CONFIG_ARCH_CHIP_TM4C129
+# error Voltage reference selection only supported in TM4C129 parts
+# endif
+#endif
+
+#ifdef CONFIG_TIVA_ADC_ALT_CLK
+# warning CONFIG_TIVA_ADC_ALT_CLK unsupported.
+#endif
+
+#ifndef CONFIG_SCHED_WORKQUEUE
+# error Work queue support is required (CONFIG_SCHED_WORKQUEUE)
+#endif
+#ifndef CONFIG_SCHED_HPWORK
+# error High priority worker threads is required (CONFIG_SCHED_HPWORK)
+#endif
+
+/* PWM trigger support definitions ******************************************/
+
+/* Decodes the PWM generator and module from trigger and converts
+ * to the TSSEL_PS register
+ */
+
+#define ADC_TRIG_PWM_CFG(t) \
+ (1<<(ADC_TSSEL_PS_SHIFT(ADC_TRIG_gen(t))))
+
+/* ADC support definitions **************************************************/
+
+#define SSE_PROC_TRIG(n) (1 << (n))
+#define SEM_PROCESS_PRIVATE 0
+#define SEM_PROCESS_SHARED 1
+
+/* DEBUG ********************************************************************/
+
+#ifdef CONFIG_DEBUG_ANALOG
+#endif
+
+/****************************************************************************
+ * Public Functions
+ * **************************************************************************/
+
+/* Upper level ADC driver ***************************************************/
+
+static void tiva_adc_reset(struct adc_dev_s *dev);
+static int tiva_adc_setup(struct adc_dev_s *dev);
+static void tiva_adc_shutdown(struct adc_dev_s *dev);
+static void tiva_adc_rxint(struct adc_dev_s *dev, bool enable);
+static int tiva_adc_ioctl(struct adc_dev_s *dev, int cmd, unsigned long arg);
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/* ADC lower half device operations */
+
+static const struct adc_ops_s g_adcops =
+{
+ .ao_reset = tiva_adc_reset,
+ .ao_setup = tiva_adc_setup,
+ .ao_shutdown = tiva_adc_shutdown,
+ .ao_rxint = tiva_adc_rxint,
+ .ao_ioctl = tiva_adc_ioctl,
+};
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct tiva_adc_s
+{
+ struct adc_dev_s *dev;
+ bool cfg; /* Configuration state */
+ bool ena; /* Operation state */
+ uint8_t devno; /* ADC device number */
+};
+
+struct tiva_adc_sse_s
+{
+ sem_t exclsem; /* Mutual exclusion semaphore */
+ struct work_s work; /* Supports the interrupt handling "bottom half" */
+ bool cfg; /* Configuration state */
+ bool ena; /* Sample sequencer operation state */
+ uint8_t adc; /* Parent peripheral */
+ uint8_t num; /* SSE number */
+};
+
+/****************************************************************************
+ * Private Function Definitions
+ ****************************************************************************/
+
+static void tiva_adc_interrupt(struct tiva_adc_sse_s *sse);
+#ifdef CONFIG_DEBUG_ANALOG
+static void tiva_adc_runtimeobj_ptrs(void);
+static void tiva_adc_runtimeobj_vals(void);
+static void tiva_adc_dump_dev(void);
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Run-time ADC objects */
+
+#ifdef CONFIG_TIVA_ADC0
+static struct adc_dev_s dev0;
+static struct tiva_adc_s adc0;
+
+static struct tiva_adc_sse_s sse00;
+static struct tiva_adc_sse_s sse01;
+static struct tiva_adc_sse_s sse02;
+static struct tiva_adc_sse_s sse03;
+#endif
+
+#ifdef CONFIG_TIVA_ADC1
+static struct adc_dev_s dev1;
+static struct tiva_adc_s adc1;
+
+static struct tiva_adc_sse_s sse10;
+static struct tiva_adc_sse_s sse11;
+static struct tiva_adc_sse_s sse12;
+static struct tiva_adc_sse_s sse13;
+#endif
+
+/* Offer run-time ADC objects in array form to help reduce the reliance on
+ * hard-coded, non-generic function calls.
+ */
+
+static struct adc_dev_s *g_devs[] =
+{
+#ifdef CONFIG_TIVA_ADC0
+ &dev0,
+#else
+ NULL,
+#endif
+#ifdef CONFIG_TIVA_ADC1
+ &dev1
+#else
+ NULL
+#endif
+};
+
+static struct tiva_adc_s *g_adcs[] =
+{
+#ifdef CONFIG_TIVA_ADC0
+ &adc0,
+#else
+ NULL,
+#endif
+#ifdef CONFIG_TIVA_ADC1
+ &adc1
+#else
+ NULL
+#endif
+};
+
+static struct tiva_adc_sse_s *g_sses[] =
+{
+#ifdef CONFIG_TIVA_ADC0
+ &sse00, &sse01, &sse02, &sse03,
+#else
+ NULL, NULL, NULL, NULL,
+#endif
+#ifdef CONFIG_TIVA_ADC1
+ &sse10, &sse11, &sse12, &sse13
+#else
+ NULL, NULL, NULL, NULL
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/* Interrupt handlers are inevitably hard-coded and specific */
+
+#ifdef CONFIG_TIVA_ADC0
+static int tiva_adc0_sse0_interrupt(int irq, void *context)
+{
+ tiva_adc_interrupt(&sse00);
+ return OK;
+}
+
+static int tiva_adc0_sse1_interrupt(int irq, void *context)
+{
+ tiva_adc_interrupt(&sse01);
+ return OK;
+}
+
+static int tiva_adc0_sse2_interrupt(int irq, void *context)
+{
+ tiva_adc_interrupt(&sse02);
+ return OK;
+}
+
+static int tiva_adc0_sse3_interrupt(int irq, void *context)
+{
+ tiva_adc_interrupt(&sse03);
+ return OK;
+}
+#endif
+
+#ifdef CONFIG_TIVA_ADC1
+static int tiva_adc1_sse0_interrupt(int irq, void *context)
+{
+ tiva_adc_interrupt(&sse10);
+ return OK;
+}
+
+static int tiva_adc1_sse1_interrupt(int irq, void *context)
+{
+ tiva_adc_interrupt(&sse11);
+ return OK;
+}
+
+static int tiva_adc1_sse2_interrupt(int irq, void *context)
+{
+ tiva_adc_interrupt(&sse12);
+ return OK;
+}
+
+static int tiva_adc1_sse3_interrupt(int irq, void *context)
+{
+ tiva_adc_interrupt(&sse13);
+ return OK;
+}
+#endif
+
+static void tiva_adc_irqinitialize(struct tiva_adc_cfg_s *cfg)
+{
+ avdbg("initialize irqs for ADC%d...\n", cfg->adc);
+
+#ifdef CONFIG_TIVA_ADC0
+ if (cfg->adc == 0)
+ {
+ if (cfg->sse[0] && (cfg->ssecfg[0].trigger > 0))
+ {
+ tiva_adc_irq_attach(0, 0, tiva_adc0_sse0_interrupt);
+ }
+
+ if (cfg->sse[1] && (cfg->ssecfg[1].trigger > 0))
+ {
+ tiva_adc_irq_attach(0, 1, tiva_adc0_sse1_interrupt);
+ }
+
+ if (cfg->sse[2] && (cfg->ssecfg[2].trigger > 0))
+ {
+ tiva_adc_irq_attach(0, 2, tiva_adc0_sse2_interrupt);
+ }
+
+ if (cfg->sse[3] && (cfg->ssecfg[3].trigger > 0))
+ {
+ tiva_adc_irq_attach(0, 3, tiva_adc0_sse3_interrupt);
+ }
+ }
+#endif
+#ifdef CONFIG_TIVA_ADC1
+ if (cfg->adc == 1)
+ {
+ if (cfg->sse[0] && (cfg->ssecfg[0].trigger > 0))
+ {
+ tiva_adc_irq_attach(1, 0, tiva_adc1_sse0_interrupt);
+ }
+
+ if (cfg->sse[1] && (cfg->ssecfg[1].trigger > 0))
+ {
+ tiva_adc_irq_attach(1, 1, tiva_adc1_sse1_interrupt);
+ }
+
+ if (cfg->sse[2] && (cfg->ssecfg[2].trigger > 0))
+ {
+ tiva_adc_irq_attach(1, 2, tiva_adc1_sse2_interrupt);
+ }
+
+ if (cfg->sse[3] && (cfg->ssecfg[3].trigger > 0))
+ {
+ tiva_adc_irq_attach(1, 3, tiva_adc1_sse3_interrupt);
+ }
+ }
+#endif
+}
+
+/****************************************************************************
+ * Name: tiva_adc_reset
+ *
+ * Description:
+ * Reset the ADC device. Called early to initialize the hardware. This is
+ * called before tiva_adc_setup() and on error conditions.
+ *
+ * Resetting disables interrupts and the enabled SSEs for the ADC.
+ *
+ ****************************************************************************/
+
+static void tiva_adc_reset(struct adc_dev_s *dev)
+{
+ avdbg("Resetting...\n");
+
+ struct tiva_adc_s *priv = (struct tiva_adc_s *)dev->ad_priv;
+ struct tiva_adc_sse_s *sse;
+ uint8_t s;
+
+ tiva_adc_rxint(dev, false);
+
+ for (s = 0; s < 4; ++s)
+ {
+ sse = g_sses[SSE_IDX(priv->devno, s)];
+
+ if (sse->ena == true)
+ {
+ tiva_adc_sse_enable(priv->devno, s, false);
+ sse->ena = false;
+ }
+ }
+}
+
+/****************************************************************************
+ * Name: tiva_adc_setup
+ *
+ * Description:
+ * Configure the ADC. This method is called the first time that the ADC
+ * device is opened. This will occur when the port is first opened.
+ * Interrupts are all disabled upon return.
+ *
+ ****************************************************************************/
+
+static int tiva_adc_setup(struct adc_dev_s *dev)
+{
+ avdbg("Setup\n");
+
+ struct tiva_adc_s *priv = (struct tiva_adc_s *)dev->ad_priv;
+ struct tiva_adc_sse_s *sse;
+ uint8_t s = 0;
+
+ priv->ena = true;
+
+ for (s = 0; s < 4; ++s)
+ {
+ sse = g_sses[SSE_IDX(priv->devno, s)];
+ if (sse->cfg == true)
+ {
+ tiva_adc_sse_enable(priv->devno, s, true);
+ sse->ena = true;
+ }
+ }
+
+ tiva_adc_rxint(dev, false);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: tiva_adc_shutdown
+ *
+ * Description:
+ * Disable the ADC. This method is called when the ADC device is closed.
+ * This method reverses the operation the setup method.
+ *
+ ****************************************************************************/
+
+static void tiva_adc_shutdown(struct adc_dev_s *dev)
+{
+ struct tiva_adc_s *priv = (struct tiva_adc_s *)dev->ad_priv;
+ avdbg("Shutdown\n");
+
+ DEBUGASSERT(priv->ena);
+
+ /* Resetting the ADC peripheral disables interrupts and all SSEs */
+
+ tiva_adc_reset(dev);
+
+ /* Currently all of the setup operations are undone in reset() */
+
+#if 0
+ struct tiva_adc_sse_s *sse;
+ uint8_t s = 0;
+
+ for (s=0; s<4; ++s)
+ {
+ }
+#endif
+
+ priv->ena = false;
+}
+
+/****************************************************************************
+ * Name: tiva_adc_rxint
+ *
+ * Description:
+ * Call to enable or disable RX interrupts
+ *
+ * Input Parameters:
+ * enable - the enable state of interrupts for this device
+ *
+ ****************************************************************************/
+
+static void tiva_adc_rxint(struct adc_dev_s *dev, bool enable)
+{
+ avdbg("RXINT=%d\n", enable);
+
+ struct tiva_adc_s *priv = (struct tiva_adc_s *)dev->ad_priv;
+ struct tiva_adc_sse_s *sse;
+ uint32_t trigger;
+ uint8_t s = 0;
+
+ DEBUGASSERT(priv->ena);
+
+ for (s=0; s<4; ++s)
+ {
+ trigger = tiva_adc_get_trigger(priv->devno, s);
+ sse = g_sses[SSE_IDX(priv->devno, s)];
+ if ((sse->ena == true)
+ && (trigger > 0))
+ {
+ tiva_adc_sse_int_enable(priv->devno, s, enable);
+ }
+ }
+}
+
+/****************************************************************************
+ * Name: tiva_adc_ioctl
+ *
+ * Description:
+ * All ioctl calls will be routed through this method.
+ *
+ * Input Parameters:
+ * cmd - ADC ioctl command
+ * arg - argument for the ioctl command
+ *
+ * Returned Value:
+ * Non negative value on success; negative value on failure.
+ *
+ ****************************************************************************/
+
+static int tiva_adc_ioctl(struct adc_dev_s *dev, int cmd, unsigned long arg)
+{
+ int ret = OK;
+
+ avdbg("cmd=%d arg=%ld\n", cmd, arg);
+
+ switch (cmd)
+ {
+ /* Software trigger */
+
+ case ANIOC_TRIGGER:
+ {
+ struct tiva_adc_s *priv = (struct tiva_adc_s *)dev->ad_priv;
+ uint8_t i = 0;
+ uint8_t fifo_count = 0;
+ uint8_t sse = (uint8_t) arg;
+ int32_t buf[8];
+
+ /* Get exclusive access to the driver data structure */
+
+ tiva_adc_lock(priv, sse);
+
+ /* Start conversion and wait for end of conversion */
+
+ tiva_adc_proc_trig(priv->devno, (uint8_t)SSE_PROC_TRIG(sse));
+ while (!tiva_adc_sse_int_status(priv->devno, sse))
+ {
+ usleep(100);
+ }
+
+ tiva_adc_sse_clear_int(priv->devno, sse);
+
+ /* Pass sampled data to upper ADC driver */
+
+ fifo_count = tiva_adc_sse_data(priv->devno, sse, buf);
+
+ for (i=0; i<fifo_count; ++i)
+ {
+ (void)adc_receive(dev,
+ tiva_adc_get_ain(priv->devno, sse, i),
+ buf[i]);
+ }
+
+ /* Release our lock on the ADC structure */
+
+ tiva_adc_unlock(priv, sse);
+ }
+ break;
+
+ /* PWM triggering */
+
+#warning Missing Logic
+
+ /* TODO: Needs to be tested */
+
+#ifdef CONFIG_EXPERIMENTAL
+ case TIVA_ADC_PWM_TRIG_IOCTL:
+ {
+ uint8_t sse = (uint8_t)(arg & 0x2);
+ uint8_t regval = tiva_adc_get_trigger(adc, sse);
+
+ /* Verify input SSE trigger is a PWM trigger */
+
+ if ((regval & TIVA_ADC_TRIG_PWM0) ||
+ (regval & TIVA_ADC_TRIG_PWM1) ||
+ (regval & TIVA_ADC_TRIG_PWM2) ||
+ (regval & TIVA_ADC_TRIG_PWM3))
+ {
+ tiva_adc_sse_pwm_trig(adc, sse, (uint32_t)(arg&0xFFFFFFFC));
+ }
+ }
+ break;
+#endif
+
+#warning Missing Logic
+
+ /* Unsupported or invalid command */
+
+ default:
+ ret = -ENOTTY;
+ break;
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: tiva_adc_read
+ *
+ * Description:
+ * This function executes on the worker thread. It is scheduled by
+ * tiva_adc_interrupt whenever any enabled event occurs. All interrupts
+ * are disabled when this function runs. tiva_adc_read will
+ * re-enable interrupts when it completes processing all pending events.
+ *
+ * Input Parameters
+ * arg - The ADC SSE data structure cast to (void *)
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void tiva_adc_read(void *arg)
+{
+ struct tiva_adc_sse_s *sse = (struct tiva_adc_sse_s *)arg;
+ struct adc_dev_s *dev = 0;
+ int irq = tiva_adc_getirq(sse->adc, sse->num);
+ uint8_t i = 0;
+ uint8_t fifo_count = 0;
+ int32_t buf[8];
+
+ /* Get exclusive access to the driver data structure */
+
+ tiva_adc_lock(g_adcs[sse->adc], sse->num);
+
+ /* Get sampled data */
+
+ fifo_count = tiva_adc_sse_data(sse->adc, sse->num, buf);
+
+ /* Determine which adc_dev_s we need */
+
+ dev = g_devs[sse->adc];
+ if (dev == NULL)
+ {
+ /* This is a serious error: indicates invalid pointer indirection
+ * and should cause a full system stop.
+ */
+ alldbg("PANIC!!! Invalid ADC device number given %d\n", sse->adc);
+ PANIC();
+ return;
+ }
+
+ for (i=0; i<fifo_count; ++i)
+ {
+ (void)adc_receive(dev,
+ tiva_adc_get_ain(sse->adc, sse->num, i),
+ buf[i]);
+ avdbg("AIN%d=0x%04x\n",
+ tiva_adc_get_ain(sse->adc, sse->num, i), buf[i]);
+ }
+
+ /* Exit, re-enabling ADC interrupts */
+
+ up_enable_irq(irq);
+
+ /* Release our lock on the ADC structure */
+
+ tiva_adc_unlock(g_adcs[sse->adc], sse->num);
+}
+
+/****************************************************************************
+ * Name: tiva_adc_interrupt
+ *
+ * Description:
+ * This function is called by every interrupt handler and handles the
+ * actual worker dispatching.
+ *
+ ****************************************************************************/
+
+static void tiva_adc_interrupt(struct tiva_adc_sse_s *sse)
+{
+ int ret;
+ int irq = tiva_adc_getirq(sse->adc, sse->num);
+
+ DEBUGASSERT(sse->ena == true);
+
+ /* disable further interrupts. Interrupts will be re-enabled
+ * after the worker thread executes.
+ */
+
+ up_disable_irq(irq);
+
+ /* Clear interrupt status */
+
+ tiva_adc_sse_clear_int(sse->adc, sse->num);
+
+ /* Transfer processing to the worker thread. Since interrupts are
+ * disabled while the work is pending, no special action should be
+ * required to protected the work queue.
+ */
+
+ DEBUGASSERT(sse->work.worker == NULL);
+ ret = work_queue(HPWORK, &sse->work, tiva_adc_read, sse, 0);
+ if (ret != 0)
+ {
+ adbg("ERROR: Failed to queue work: %d ADC.SSE: %d.%d\n",
+ ret, sse->adc, sse->num);
+ }
+}
+
+/****************************************************************************
+ * Name: tiva_adc_struct_init
+ *
+ * Description:
+ * Initialize public and private adc structures their member SSE's.
+ *
+ ****************************************************************************/
+
+static struct tiva_adc_s *tiva_adc_struct_init(struct tiva_adc_cfg_s *cfg)
+{
+ struct tiva_adc_s *adc = g_adcs[cfg->adc];
+ struct tiva_adc_sse_s *sse = 0;
+ uint8_t s = 0;
+
+ /* Do not re-initialize the run-time structures, there is a chance another
+ * process is also using this ADC.
+ */
+
+ if (adc->cfg == true)
+ {
+ goto tiva_adc_struct_init_ok;
+ }
+ else
+ {
+ if (adc != NULL)
+ {
+ adc->ena = false;
+ adc->devno = cfg->adc;
+
+ for (s=0; s<4; s++)
+ {
+
+ /* Only configure selected SSEs */
+
+ if (cfg->sse[s])
+ {
+ sse = g_sses[SSE_IDX(cfg->adc, s)];
+
+ if (sse != NULL)
+ {
+ sse->adc = cfg->adc;
+ sse->num = s;
+ sem_init(&sse->exclsem, SEM_PROCESS_PRIVATE, 1);
+ sse->ena = false;
+ sse->cfg = true;
+ }
+ else
+ {
+ goto tiva_adc_struct_init_error;
+ }
+ }
+ }
+
+ /* Initialize the public ADC device data structure */
+
+ adc->dev = g_devs[cfg->adc];
+ if (adc->dev != NULL)
+ {
+ adc->dev->ad_ops = &g_adcops;
+ adc->dev->ad_priv = adc;
+ }
+ else
+ {
+ goto tiva_adc_struct_init_error;
+ }
+ goto tiva_adc_struct_init_ok;
+ }
+ else
+ {
+ goto tiva_adc_struct_init_error;
+ }
+ }
+
+tiva_adc_struct_init_error:
+ avdbg("Invalid ADC device number: expected=%d actual=%d\n",
+ 0, cfg->adc);
+ avdbg("ADC%d (CONFIG_TIVA_ADC%d) must be enabled in Kconfig first!",
+ cfg->adc, cfg->adc);
+ return NULL;
+
+tiva_adc_struct_init_ok:
+ adc->cfg = true;
+ return adc;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: tiva_adc_initialize
+ *
+ * Description:
+ * Configuration and bind the ADC to the ADC lower half instance and
+ * register the ADC driver at 'devpath'.
+ *
+ * Input Parameters:
+ * devpath - The full path to the ADC device. This should be of the
+ * form /dev/adc0
+ * cfg - ADC configuration structure, configures the whole ADC.
+ * clock - clock speed for all ADC's. This is only set once for the first
+ * call to tiva_adc_initialize, otherwise the values are ignored.
+ * sample_rate - maximum sample rate of any ADC. This is only set once
+ * for the first call to tiva_adc_initialize, otherwise the values are
+ * ignored.
+ *
+ ****************************************************************************/
+
+int tiva_adc_initialize(const char *devpath, struct tiva_adc_cfg_s *cfg,
+ uint32_t clock, uint8_t sample_rate)
+{
+ struct tiva_adc_s *adc;
+ int ret = 0;
+
+ avdbg("initializing...\n");
+
+ /* Initialize the private ADC device data structure */
+
+ adc = tiva_adc_struct_init(cfg);
+ if (adc == NULL)
+ {
+ adbg("Invalid ADC device number: expected=%d actual=%d\n",
+ 0, cfg->adc);
+ return -ENODEV;
+ }
+
+ /* Turn on peripheral */
+
+ if (tiva_adc_enable(adc->devno, true) < 0)
+ {
+ adbg("ERROR: failure to power ADC peripheral (devno=%d)\n",
+ cfg->adc);
+ return ret;
+ }
+
+ /* Perform actual initialization */
+
+ tiva_adc_one_time_init(clock, sample_rate);
+ tiva_adc_configure(cfg);
+ tiva_adc_irqinitialize(cfg);
+
+ /* Now we are initialized */
+
+ adc->ena = true;
+
+#ifdef CONFIG_DEBUG_ANALOG
+ tiva_adc_runtimeobj_vals();
+#endif
+
+ /* Ensure our lower half is valid */
+
+ if (adc->dev == NULL)
+ {
+ adbg("ERROR: Failed to get interface %s\n", devpath);
+ return -ENODEV;
+ }
+
+ avdbg("adc_dev_s=0x%08x\n", adc->dev);
+
+ /* Register the ADC driver */
+
+ avdbg("Register the ADC driver at %s\n", devpath);
+
+ ret = adc_register(devpath, adc->dev);
+ if (ret < 0)
+ {
+ adbg("ERROR: Failed to register %s to character driver: %d\n",
+ devpath, ret);
+ return ret;
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: tiva_adc_lock
+ *
+ * Description:
+ * Get exclusive access to the ADC interface
+ *
+ ****************************************************************************/
+
+void tiva_adc_lock(FAR struct tiva_adc_s *priv, int sse)
+{
+ avdbg("Locking...\n");
+
+ struct tiva_adc_sse_s *s = g_sses[SSE_IDX(priv->devno, sse)];
+ int ret;
+#ifdef CONFIG_DEBUG_ANALOG
+ uint16_t loop_count=0;
+#endif
+
+ do
+ {
+ ret = sem_wait(&s->exclsem);
+
+ /* This should only fail if the wait was canceled by an signal (and the
+ * worker thread will receive a lot of signals).
+ */
+
+ DEBUGASSERT(ret == OK || errno == EINTR);
+
+#ifdef CONFIG_DEBUG_ANALOG
+ if (loop_count % 1000)
+ {
+ avdbg("loop=%d\n");
+ }
+ ++loop_count;
+#endif
+ }
+ while (ret < 0);
+}
+
+/****************************************************************************
+ * Name: tiva_adc_unlock
+ *
+ * Description:
+ * Relinquish the lock on the ADC interface
+ *
+ ****************************************************************************/
+
+void tiva_adc_unlock(FAR struct tiva_adc_s *priv, int sse)
+{
+ avdbg("Unlocking\n");
+ struct tiva_adc_sse_s *s = g_sses[SSE_IDX(priv->devno, sse)];
+ sem_post(&s->exclsem);
+}
+
+/* DEBUG ********************************************************************/
+
+#ifdef CONFIG_DEBUG_ANALOG
+
+/****************************************************************************
+ * Name: tiva_adc_runtimeobj_ptrs
+ *
+ * Description:
+ * Dumps the address of all run-time objects for verification.
+ *
+ ****************************************************************************/
+
+static void tiva_adc_runtimeobj_ptrs(void)
+{
+# ifdef CONFIG_TIVA_ADC0
+ avdbg("ADC0 [struct] [global value] [array value]\n");
+ avdbg(" adc_dev_s dev0=0x%08x g_devs[0]=0x%08x\n", &dev0, g_devs[0]);
+ avdbg(" tiva_adc_s adc0=0x%08x g_adcs[0]=0x%08x\n", &adc0, g_adcs[0]);
+ avdbg(" tiva_adc_sse_s sse0=0x%08x g_sses[0,0]=0x%08x\n", &sse00, g_sses[SSE_IDX(0,0)]);
+ avdbg(" tiva_adc_sse_s sse1=0x%08x g_sses[0,1]=0x%08x\n", &sse01, g_sses[SSE_IDX(0,1)]);
+ avdbg(" tiva_adc_sse_s sse2=0x%08x g_sses[0,2]=0x%08x\n", &sse02, g_sses[SSE_IDX(0,2)]);
+ avdbg(" tiva_adc_sse_s sse3=0x%08x g_sses[0,3]=0x%08x\n", &sse03, g_sses[SSE_IDX(0,3)]);
+# endif
+# ifdef CONFIG_TIVA_ADC1
+ avdbg("ADC1 [struct] [global value] [array value]\n");
+ avdbg(" adc_dev_s dev1=0x%08x g_devs[1]=0x%08x\n", &dev1, g_devs[1]);
+ avdbg(" tiva_adc_s adc1=0x%08x g_adcs[1]=0x%08x\n", &adc1, g_adcs[1]);
+ avdbg(" tiva_adc_sse_s sse0=0x%08x g_sses[1,0]=0x%08x\n", &sse10, g_sses[SSE_IDX(1,0)]);
+ avdbg(" tiva_adc_sse_s sse1=0x%08x g_sses[1,1]=0x%08x\n", &sse11, g_sses[SSE_IDX(1,1)]);
+ avdbg(" tiva_adc_sse_s sse2=0x%08x g_sses[1,2]=0x%08x\n", &sse12, g_sses[SSE_IDX(1,2)]);
+ avdbg(" tiva_adc_sse_s sse3=0x%08x g_sses[1,3]=0x%08x\n", &sse13, g_sses[SSE_IDX(1,3)]);
+# endif
+}
+
+static void tiva_adc_runtimeobj_vals(void)
+{
+ struct tiva_adc_sse_s *sse;
+ uint8_t s;
+# ifdef CONFIG_TIVA_ADC0
+ avdbg("ADC0 [0x%08x] cfg=%d ena=%d devno=%d\n",
+ &adc0, adc0.cfg, adc0.ena, adc0.devno);
+ for (s=0; s<4; ++s)
+ {
+ sse = g_sses[SSE_IDX(0, s)];
+ avdbg("SSE%d [0x%08x] adc=%d cfg=%d ena=%d num=%d\n",
+ s, sse, sse->adc, sse->cfg, sse->ena, sse->num);
+ }
+# endif
+# ifdef CONFIG_TIVA_ADC1
+ avdbg("ADC1 [0x%08x] cfg=%d ena=%d devno=%d\n",
+ &adc1, adc1.cfg, adc1.ena, adc1.devno);
+ for (s=0; s<4; ++s)
+ {
+ sse = g_sses[SSE_IDX(1, s)];
+ avdbg("SSE%d [0x%08x] adc=%d cfg=%d ena=%d num=%d\n",
+ s, sse, sse->adc, sse->cfg, sse->ena, sse->num);
+ }
+# endif
+}
+
+/****************************************************************************
+ * Name: tiva_adc_unlock
+ *
+ * Description:
+ * umps the device level objects for verification.
+ *
+ ****************************************************************************/
+
+static void tiva_adc_dump_dev(void)
+{
+# ifdef CONFIG_TIVA_ADC0
+ avdbg("adc_ops_s g_adcops=0x%08x adc0.dev->ad_ops=0x%08x\n",
+ &g_adcops, adc0.dev->ad_ops);
+ avdbg("tiva_adc_s adc0=0x%08x adc0.dev->ad_priv=0x%08x\n",
+ &adc0, adc0.dev->ad_priv);
+# endif
+# ifdef CONFIG_TIVA_ADC1
+ avdbg("adc_ops_s g_adcops=0x%08x adc1.dev->ad_ops=0x%08x\n",
+ &g_adcops, adc1.dev->ad_ops);
+ avdbg("tiva_adc_s adc1=0x%08x adc1.dev->ad_priv=0x%08x\n",
+ &adc1, adc1.dev->ad_priv);
+# endif
+}
+#endif
+
+#endif /* CONFIG_TIVA_ADC && CONFIG_ADC */
diff --git a/nuttx/arch/arm/src/tiva/tiva_gpio.c b/nuttx/arch/arm/src/tiva/tiva_gpio.c
index 6960dee3b..e02b17f88 100644
--- a/nuttx/arch/arm/src/tiva/tiva_gpio.c
+++ b/nuttx/arch/arm/src/tiva/tiva_gpio.c
@@ -1,7 +1,7 @@
/****************************************************************************
* arch/arm/src/tiva/tiva_gpio.c
*
- * Copyright (C) 2009-2010, 2014 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2009-2010, 2014-2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -222,7 +222,7 @@ static const uintptr_t g_gpiobase[TIVA_NPORTS] =
*
****************************************************************************/
-uintptr_t tiva_gpiobaseaddress(unsigned int port)
+inline uintptr_t tiva_gpiobaseaddress(unsigned int port)
{
uintptr_t gpiobase = 0;
if (port < TIVA_NPORTS)
@@ -237,7 +237,8 @@ uintptr_t tiva_gpiobaseaddress(unsigned int port)
* Name: tiva_gpiofunc
*
* Description:
- * Configure GPIO registers for a specific function
+ * Configure GPIO registers for a specific function. Overwrites certain
+ * padtype configurations.
*
****************************************************************************/
@@ -246,31 +247,64 @@ static void tiva_gpiofunc(uint32_t base, uint32_t pinno,
{
uint32_t setbit;
uint32_t clrbit;
- uint32_t regval;
- /* Set/clear/ignore the GPIO ODR bit. "The GPIO ODR register is the open drain
- * control register. Setting a bit in this register enables the open drain
- * configuration of the corresponding GPIO pad. When open drain mode is enabled,
- * the corresponding bit should also be set in the GPIO Digital Input Enable
- * (GPIO DEN) register ... Corresponding bits in the drive strength registers
- * (GPIO DR2R, GPIO DR4R, GPIO DR8R, and GPIO SLR ) can be set to achieve the
- * desired rise and fall times. The GPIO acts as an open drain input if the
- * corresponding bit in the GPIO DIR register is set to 0; and as an open
- * drain output when set to 1."
+ /* Set/clear/ignore the GPIO DIR bit. "The GPIODIR register is the data
+ * direction register. Bits set to 1 in the GPIODIR register configure
+ * the corresponding pin to be an output, while bits set to 0 configure
+ * the pins to be inputs. All bits are cleared by a reset, meaning all
+ * GPIO pins are inputs by default.
+ */
+
+ setbit = (((uint32_t)func->setbits >> DIR_SHIFT) & 1) << pinno;
+ clrbit = (((uint32_t)func->clrbits >> DIR_SHIFT) & 1) << pinno;
+
+ if (setbit || clrbit)
+ {
+ modifyreg32(base + TIVA_GPIO_DIR_OFFSET, clrbit, setbit);
+ }
+
+ /* Set/clear/ignore the GPIO AFSEL bit. "The GPIOAFSEL register is the
+ * mode control select register. Writing a 1 to any bit in this register
+ * selects the hardware control for the corresponding GPIO line. All bits
+ * are cleared by a reset, therefore no GPIO line is set to hardware
+ * control by default."
+ *
+ * NOTE: In order to set JTAG/SWD GPIOs, it is also necessary to lock,
+ * commit and unlock the GPIO. That is not implemented here.
+ */
+
+ setbit = (((uint32_t)func->setbits >> AFSEL_SHIFT) & 1) << pinno;
+ clrbit = (((uint32_t)func->clrbits >> AFSEL_SHIFT) & 1) << pinno;
+
+ if (setbit || clrbit)
+ {
+ modifyreg32(base + TIVA_GPIO_AFSEL_OFFSET, clrbit, setbit);
+ }
+
+ /* Set/clear/ignore the GPIO ODR bit. "The GPIO ODR register is the open
+ * drain control register. Setting a bit in this register enables the open
+ * drain configuration of the corresponding GPIO pad. When open drain mode
+ * is enabled, the corresponding bit should also be set in the GPIO Digital
+ * Input Enable (GPIO DEN) register ... Corresponding bits in the drive
+ * strength registers (GPIO DR2R, GPIO DR4R, GPIO DR8R, and GPIO SLR ) can
+ * be set to achieve the desired rise and fall times. The GPIO acts as an
+ * open drain input if the corresponding bit in the GPIO DIR register is
+ * set to 0; and as an open drain output when set to 1."
*/
setbit = (((uint32_t)func->setbits >> ODR_SHIFT) & 1) << pinno;
clrbit = (((uint32_t)func->clrbits >> ODR_SHIFT) & 1) << pinno;
- regval = getreg32(base + TIVA_GPIO_ODR_OFFSET);
- regval &= ~clrbit;
- regval |= setbit;
- putreg32(regval, base + TIVA_GPIO_ODR_OFFSET);
+ if (setbit || clrbit)
+ {
+ modifyreg32(base + TIVA_GPIO_ODR_OFFSET, clrbit, setbit);
+ }
- /* Set/clear the GPIO PUR bit. "The GPIOPUR register is the pull-up control
- * register. When a bit is set to 1, it enables a weak pull-up resistor on the
- * corresponding GPIO signal. Setting a bit in GPIOPUR automatically clears the
- * corresponding bit in the GPIO Pull-Down Select (GPIOPDR) register ..."
+ /* Set/clear the GPIO PUR bit. "The GPIOPUR register is the pull-up
+ * control register. When a bit is set to 1, it enables a weak pull-up
+ * resistor on the corresponding GPIO signal. Setting a bit in GPIOPUR
+ * automatically clears the corresponding bit in the GPIO Pull-Down
+ * Select (GPIOPDR) register ..."
*/
setbit = (((uint32_t)func->setbits >> PUR_SHIFT) & 1) << pinno;
@@ -278,16 +312,14 @@ static void tiva_gpiofunc(uint32_t base, uint32_t pinno,
if (setbit || clrbit)
{
- regval = getreg32(base + TIVA_GPIO_PUR_OFFSET);
- regval &= ~clrbit;
- regval |= setbit;
- putreg32(regval, base + TIVA_GPIO_PUR_OFFSET);
+ modifyreg32(base + TIVA_GPIO_PUR_OFFSET, clrbit, setbit);
}
- /* Set/clear the GPIO PDR bit. "The GPIOPDR register is the pull-down control
- * register. When a bit is set to 1, it enables a weak pull-down resistor on the
- * corresponding GPIO signal. Setting a bit in GPIOPDR automatically clears
- * the corresponding bit in the GPIO Pull-Up Select (GPIOPUR) register ..."
+ /* Set/clear the GPIO PDR bit. "The GPIOPDR register is the pull-down
+ * control register. When a bit is set to 1, it enables a weak pull-down
+ * resistor on the corresponding GPIO signal. Setting a bit in GPIOPDR
+ * automatically clears the corresponding bit in the GPIO Pull-Up Select
+ * (GPIOPUR) register ..."
*/
setbit = (((uint32_t)func->setbits >> PDR_SHIFT) & 1) << pinno;
@@ -295,61 +327,27 @@ static void tiva_gpiofunc(uint32_t base, uint32_t pinno,
if (setbit || clrbit)
{
- regval = getreg32(base + TIVA_GPIO_PDR_OFFSET);
- regval &= ~clrbit;
- regval |= setbit;
- putreg32(regval, base + TIVA_GPIO_PDR_OFFSET);
+ modifyreg32(base + TIVA_GPIO_PDR_OFFSET, clrbit, setbit);
}
/* Set/clear the GPIO DEN bit. "The GPIODEN register is the digital enable
- * register. By default, with the exception of the GPIO signals used for JTAG/SWD
- * function, all other GPIO signals are configured out of reset to be undriven
- * (tristate). Their digital function is disabled; they do not drive a logic
- * value on the pin and they do not allow the pin voltage into the GPIO receiver.
- * To use the pin in a digital function (either GPIO or alternate function), the
- * corresponding GPIODEN bit must be set."
+ * register. By default, with the exception of the GPIO signals used for
+ * JTAG/SWD function, all other GPIO signals are configured out of reset
+ * to be undriven (tristate). Their digital function is disabled; they do
+ * not drive a logic value on the pin and they do not allow the pin voltage
+ * into the GPIO receiver. To use the pin in a digital function (either
+ * GPIO or alternate function), the corresponding GPIODEN bit must be set."
*/
setbit = (((uint32_t)func->setbits >> DEN_SHIFT) & 1) << pinno;
clrbit = (((uint32_t)func->clrbits >> DEN_SHIFT) & 1) << pinno;
- regval = getreg32(base + TIVA_GPIO_DEN_OFFSET);
- regval &= ~clrbit;
- regval |= setbit;
- putreg32(regval, base + TIVA_GPIO_DEN_OFFSET);
-
- /* Set/clear/ignore the GPIO DIR bit. "The GPIODIR register is the data
- * direction register. Bits set to 1 in the GPIODIR register configure
- * the corresponding pin to be an output, while bits set to 0 configure the
- * pins to be inputs. All bits are cleared by a reset, meaning all GPIO
- * pins are inputs by default.
- */
-
- setbit = (((uint32_t)func->setbits >> DIR_SHIFT) & 1) << pinno;
- clrbit = (((uint32_t)func->clrbits >> DIR_SHIFT) & 1) << pinno;
-
- regval = getreg32(base + TIVA_GPIO_DIR_OFFSET);
- regval &= ~clrbit;
- regval |= setbit;
- putreg32(regval, base + TIVA_GPIO_DIR_OFFSET);
-
- /* Set/clear/ignore the GPIO AFSEL bit. "The GPIOAFSEL register is the mode
- * control select register. Writing a 1 to any bit in this register selects
- * the hardware control for the corresponding GPIO line. All bits are cleared
- * by a reset, therefore no GPIO line is set to hardware control by default."
- *
- * NOTE: In order so set JTAG/SWD GPIOs, it is also necessary to lock, commit
- * and unlock the GPIO. That is not implemented here.
- */
-
- setbit = (((uint32_t)func->setbits >> AFSEL_SHIFT) & 1) << pinno;
- clrbit = (((uint32_t)func->clrbits >> AFSEL_SHIFT) & 1) << pinno;
-
- regval = getreg32(base + TIVA_GPIO_AFSEL_OFFSET);
- regval &= ~clrbit;
- regval |= setbit;
- putreg32(regval, base + TIVA_GPIO_AFSEL_OFFSET);
+ if (setbit || clrbit)
+ {
+ modifyreg32(base + TIVA_GPIO_DEN_OFFSET, clrbit, setbit);
+ }
+#if defined(LM4F) || defined(TM4C)
/* Set/clear/ignore the GPIO AMSEL bit. "The GPIOAMSEL register controls
* isolation circuits to the analog side of a unified I/O pad. Because
* the GPIOs may be driven by a 5-V source and affect analog operation,
@@ -358,14 +356,13 @@ static void tiva_gpiofunc(uint32_t base, uint32_t pinno,
* isolation circuitry for the corresponding GPIO signal.
*/
-#if defined(LM4F) || defined(TM4C)
setbit = (((uint32_t)func->setbits >> AMSEL_SHIFT) & 1) << pinno;
clrbit = (((uint32_t)func->clrbits >> AMSEL_SHIFT) & 1) << pinno;
- regval = getreg32(base + TIVA_GPIO_AMSEL_OFFSET);
- regval &= ~clrbit;
- regval |= setbit;
- putreg32(regval, base + TIVA_GPIO_AMSEL_OFFSET);
+ if (setbit || clrbit)
+ {
+ modifyreg32(base + TIVA_GPIO_AMSEL_OFFSET, clrbit, setbit);
+ }
#endif
}
@@ -378,83 +375,106 @@ static void tiva_gpiofunc(uint32_t base, uint32_t pinno,
****************************************************************************/
static inline void tiva_gpiopadstrength(uint32_t base, uint32_t pin,
- uint32_t cfgset)
+ uint32_t pinset)
{
- int strength = (cfgset & GPIO_STRENGTH_MASK) >> GPIO_STRENGTH_SHIFT;
- uint32_t regoffset;
- uint32_t regval;
- uint32_t slrset;
- uint32_t slrclr;
-
- /* Prepare bits to disable slew */
-
- slrset = 0;
- slrclr = pin;
+ int strength = (pinset & GPIO_STRENGTH_MASK);
+ uint32_t slrset = 0;
+ uint32_t slrclr = 0;
+ uint32_t dr2rset = 0;
+ uint32_t dr2rclr = 0;
+ uint32_t dr4rset = 0;
+ uint32_t dr4rclr = 0;
+ uint32_t dr8rset = 0;
+ uint32_t dr8rclr = 0;
+
+ /* Set the output drive strength. */
switch (strength)
{
- case 0: /* 2mA pad drive strength */
+ case GPIO_STRENGTH_2MA:
{
- /* "The GPIODR2R register is the 2-mA drive control register. It
- * allows for each GPIO signal in the port to be individually configured
- * without affecting the other pads. When writing a DRV2 bit for a GPIO
- * signal, the corresponding DRV4 bit in the GPIO DR4R register and the
- * DRV8 bit in the GPIODR8R register are automatically cleared by hardware."
- */
-
- regoffset = TIVA_GPIO_DR2R_OFFSET;
+ dr2rset = pin;
+ dr4rclr = pin;
+ dr8rclr = pin;
+ slrclr = pin;
}
break;
- case 1: /* 4mA pad drive strength */
+ case GPIO_STRENGTH_4MA:
{
- /* "The GPIODR4R register is the 4-mA drive control register. It allows
- * for each GPIO signal in the port to be individually configured without
- * affecting the other pads. When writing the DRV4 bit for a GPIO signal,
- * the corresponding DRV2 bit in the GPIO DR2R register and the DRV8 bit
- * in the GPIO DR8R register are automatically cleared by hardware."
- */
-
- regoffset = TIVA_GPIO_DR4R_OFFSET;
+ dr2rclr = pin;
+ dr4rset = pin;
+ dr8rclr = pin;
+ slrclr = pin;
}
break;
- case 3: /* 8mA Pad drive with slew rate control */
+ case GPIO_STRENGTH_8MA:
{
- /* "The GPIOSLR register is the slew rate control register. Slew rate
- * control is only available when using the 8-mA drive strength option
- * via the GPIO 8-mA Drive Select (GPIODR8R) register..."
- */
+ dr2rclr = pin;
+ dr4rclr = pin;
+ dr8rset = pin;
+ slrclr = pin;
+ }
+ break;
+ case GPIO_STRENGTH_8MASC:
+ {
+ dr2rclr = pin;
+ dr4rclr = pin;
+ dr8rset = pin;
slrset = pin;
- slrclr = 0;
}
- /* Fall through */
+ break;
- case 2: /* 8mA pad drive strength (without slew rate control) */
+#ifdef CONFIG_ARCH_CHIP_TM4C129
+# if 0
+ case GPIO_STRENGTH_10MA:
+ {
+ }
+ break;
+
+ case GPIO_STRENGTH_10MASC:
+ {
+ }
+ break;
+
+ case GPIO_STRENGTH_12MA:
+ {
+ }
+ break;
+
+ case GPIO_STRENGTH_12MASC:
{
- /* "The GPIODR8R register is the 8-mA drive control register. It
- * allows for each GPIO signal in the port to be individually configured
- * without affecting the other pads. When writing the DRV8 bit for a GPIO
- * signal, the corresponding DRV2 bit in the GPIO DR2R register and the
- * DRV4 bit in the GPIO DR4R register are automatically cleared by hardware."
- */
-
- regoffset = TIVA_GPIO_DR8R_OFFSET;
}
break;
- }
- /* Set the selected pad strength and set/clear optional slew rate control */
+# endif
+#endif
+ default:
+ break;
+ }
- regval = getreg32(base + regoffset);
- regval |= pin;
- putreg32(regval, base + regoffset);
+ modifyreg32(base + TIVA_GPIO_DR2R_OFFSET, dr2rclr, dr2rset);
+ modifyreg32(base + TIVA_GPIO_DR4R_OFFSET, dr4rclr, dr4rset);
+ modifyreg32(base + TIVA_GPIO_DR8R_OFFSET, dr8rclr, dr8rset);
+ modifyreg32(base + TIVA_GPIO_SLR_OFFSET, slrclr, slrset);
+
+#ifdef CONFIG_ARCH_CHIP_TM4C129
+/* TODO: Add TM4C129 registers (TIVA_GPIO_DR12R) */
+# if 0
+ /* Set the 12-mA drive select register. This register only appears in
+ * TM4E111 and later device classes, but is a harmless write on older
+ * devices.
+ */
- regval = getreg32(base + TIVA_GPIO_SLR_OFFSET);
- regval &= slrclr;
- regval |= slrset;
- putreg32(regval, base + TIVA_GPIO_SLR_OFFSET);
+ /* Set the GPIO peripheral configuration register first as required. This
+ * register only appears in TM4E111 and later device classes, but is a
+ * harmless write on older devices. Walk pins 0-7 and clear or set the
+ * provided PC[EDMn] encoding.
+ */
+# endif // 0
+#endif
}
/****************************************************************************
@@ -468,150 +488,109 @@ static inline void tiva_gpiopadstrength(uint32_t base, uint32_t pin,
****************************************************************************/
static inline void tiva_gpiopadtype(uint32_t base, uint32_t pin,
- uint32_t cfgset)
+ uint32_t pinset)
{
- int padtype = (cfgset & GPIO_PADTYPE_MASK) >> GPIO_PADTYPE_SHIFT;
-#if 0 /* always overwritten by tiva_gpiofunc */
- uint32_t odrset;
- uint32_t odrclr;
-#endif
- uint32_t purset;
- uint32_t purclr;
- uint32_t pdrset;
- uint32_t pdrclr;
-#if 0 /* always overwritten by tiva_gpiofunc */
- uint32_t denset;
- uint32_t denclr;
-#endif
- uint32_t regval;
-
- /* Assume digital GPIO function, push-pull with no pull-up or pull-down */
-
-#if 0 /* always overwritten by tiva_gpiofunc */
- odrset = 0;
- odrclr = pin;
-#endif
- purset = 0;
- purclr = pin;
- pdrset = 0;
- pdrclr = pin;
-#if 0 /* always overwritten by tiva_gpiofunc */
- denset = pin;
- denclr = 0;
-#endif
-
- switch (padtype)
+ int padtype = (pinset & GPIO_PADTYPE_MASK);
+ uint32_t odrset = 0;
+ uint32_t odrclr = 0;
+ uint32_t purset = 0;
+ uint32_t purclr = 0;
+ uint32_t pdrset = 0;
+ uint32_t pdrclr = 0;
+ uint32_t denset = 0;
+ uint32_t denclr = 0;
+ uint32_t amselset = 0;
+ uint32_t amselclr = 0;
+
+ /* Set the pin type. */
+
+ switch(padtype)
{
- case 0: /* Push-pull */
- default:
+ case GPIO_PADTYPE_STD:
{
+ odrclr = pin;
+ purclr = pin;
+ pdrclr = pin;
+ denset = pin;
+ amselclr = pin;
}
break;
- case 1: /* Push-pull with weak pull-up */
+ case GPIO_PADTYPE_STDWPU:
{
+ odrclr = pin;
purset = pin;
- purclr = 0;
+ pdrclr = pin;
+ denset = pin;
+ amselclr = pin;
}
break;
- case 2: /* Push-pull with weak pull-down */
+
+ case GPIO_PADTYPE_STDWPD:
{
+ odrclr = pin;
+ purclr = pin;
pdrset = pin;
- pdrclr = 0;
+ denset = pin;
+ amselclr = pin;
}
break;
- case 3: /* Open-drain */
+
+ case GPIO_PADTYPE_OD:
{
-#if 0 /* always overwritten by tiva_gpiofunc */
odrset = pin;
- odrclr = 0;
-#endif
+ purclr = pin;
+ pdrclr = pin;
+ denset = pin;
+ amselclr = pin;
}
break;
- case 4: /* Open-drain with weak pull-up */
+
+ case GPIO_PADTYPE_ODWPU:
{
-#if 0 /* always overwritten by tiva_gpiofunc */
odrset = pin;
- odrclr = 0;
-#endif
purset = pin;
- purclr = 0;
+ pdrclr = pin;
+ denclr = pin;
+ amselclr = pin;
}
break;
- case 5: /* Open-drain with weak pull-down */
+
+ case GPIO_PADTYPE_ODWPD:
{
-#if 0 /* always overwritten by tiva_gpiofunc */
odrset = pin;
- odrclr = 0;
-#endif
+ purclr = pin;
pdrset = pin;
- pdrclr = 0;
+ denclr = pin;
+ amselclr = pin;
}
break;
- case 6: /* Analog comparator */
+
+ case GPIO_PADTYPE_ANALOG:
{
-#if 0 /* always overwritten by tiva_gpiofunc */
- denset = 0;
+ odrclr = pin;
+ purclr = pin;
+ pdrclr = pin;
denclr = pin;
-#endif
+ amselset = pin;
}
break;
- }
-
- /* Set/clear the GPIO ODR bit. "The GPIO ODR register is the open drain
- * control register. Setting a bit in this register enables the open drain
- * configuration of the corresponding GPIO pad. When open drain mode is enabled,
- * the corresponding bit should also be set in the GPIO Digital Input Enable
- * (GPIO DEN) register ... Corresponding bits in the drive strength registers
- * (GPIO DR2R, GPIO DR4R, GPIO DR8R, and GPIO SLR ) can be set to achieve the
- * desired rise and fall times. The GPIO acts as an open drain input if the
- * corresponding bit in the GPIO DIR register is set to 0; and as an open
- * drain output when set to 1."
- */
-
-#if 0 /* always overwritten by tiva_gpiofunc */
- regval = getreg32(base + TIVA_GPIO_ODR_OFFSET);
- regval &= ~odrclr;
- regval |= odrset;
- putreg32(regval, base + TIVA_GPIO_ODR_OFFSET);
-#endif
-
- /* Set/clear the GPIO PUR bit. "The GPIOPUR register is the pull-up control
- * register. When a bit is set to 1, it enables a weak pull-up resistor on the
- * corresponding GPIO signal. Setting a bit in GPIOPUR automatically clears the
- * corresponding bit in the GPIO Pull-Down Select (GPIOPDR) register ..."
- */
- regval = getreg32(base + TIVA_GPIO_PUR_OFFSET);
- regval &= ~purclr;
- regval |= purset;
- putreg32(regval, base + TIVA_GPIO_PUR_OFFSET);
-
- /* Set/clear the GPIO PDR bit. "The GPIOPDR register is the pull-down control
- * register. When a bit is set to 1, it enables a weak pull-down resistor on the
- * corresponding GPIO signal. Setting a bit in GPIOPDR automatically clears
- * the corresponding bit in the GPIO Pull-Up Select (GPIOPUR) register ..."
- */
+ default:
+ break;
+ }
- regval = getreg32(base + TIVA_GPIO_PDR_OFFSET);
- regval &= ~pdrclr;
- regval |= pdrset;
- putreg32(regval, base + TIVA_GPIO_PDR_OFFSET);
+ modifyreg32(base + TIVA_GPIO_ODR_OFFSET, odrclr, odrset);
+ modifyreg32(base + TIVA_GPIO_PUR_OFFSET, purclr, purset);
+ modifyreg32(base + TIVA_GPIO_PDR_OFFSET, pdrclr, pdrset);
+ modifyreg32(base + TIVA_GPIO_DEN_OFFSET, denclr, denset);
+ modifyreg32(base + TIVA_GPIO_AMSEL_OFFSET, amselclr, amselset);
- /* Set/clear the GPIO DEN bit. "The GPIODEN register is the digital enable
- * register. By default, with the exception of the GPIO signals used for JTAG/SWD
- * function, all other GPIO signals are configured out of reset to be undriven
- * (tristate). Their digital function is disabled; they do not drive a logic
- * value on the pin and they do not allow the pin voltage into the GPIO receiver.
- * To use the pin in a digital function (either GPIO or alternate function), the
- * corresponding GPIODEN bit must be set."
+#ifdef CONFIG_ARCH_CHIP_TM4C129
+ /* Set the wake pin enable register and the wake level register. These
+ * registers only appear in TM4E111 and later device classes, but are
+ * harmless writes on older devices.
*/
-
-#if 0 /* always overwritten by tiva_gpiofunc */
- regval = getreg32(base + TIVA_GPIO_DEN_OFFSET);
- regval &= ~denclr;
- regval |= denset;
- putreg32(regval, base + TIVA_GPIO_DEN_OFFSET);
#endif
}
@@ -623,10 +602,10 @@ static inline void tiva_gpiopadtype(uint32_t base, uint32_t pin,
*
****************************************************************************/
-static inline void tiva_initoutput(uint32_t cfgset)
+static inline void tiva_initoutput(uint32_t pinset)
{
- bool value = ((cfgset & GPIO_VALUE_MASK) != GPIO_VALUE_ZERO);
- tiva_gpiowrite(cfgset, value);
+ bool value = ((pinset & GPIO_VALUE_MASK) != GPIO_VALUE_ZERO);
+ tiva_gpiowrite(pinset, value);
}
/****************************************************************************
@@ -637,96 +616,72 @@ static inline void tiva_initoutput(uint32_t cfgset)
*
****************************************************************************/
-static inline void tiva_interrupt(uint32_t base, uint32_t pin, uint32_t cfgset)
+static inline void tiva_interrupt(uint32_t pinset)
{
- int inttype = (cfgset & GPIO_INT_MASK) >> GPIO_INT_SHIFT;
- uint32_t regval;
- uint32_t isset;
- uint32_t isclr;
- uint32_t ibeset;
- uint32_t ibeclr;
- uint32_t iveset;
- uint32_t iveclr;
-
- /* Mask and clear the GPIO interrupt
- *
- * "The GPIOIM register is the interrupt mask register. Bits set to High in
- * GPIO IM allow the corresponding pins to trigger their individual interrupts
- * and the combined GPIO INTR line. Clearing a bit disables interrupt triggering
- * on that pin. All bits are cleared by a reset."
- */
+ uint8_t port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
+ uint8_t pin = 1 << (pinset & GPIO_PIN_MASK);
+ uintptr_t base = tiva_gpiobaseaddress(port);
+ uint32_t inttype = pinset & GPIO_INT_MASK;
- regval = getreg32(base + TIVA_GPIO_IM_OFFSET);
- regval &= ~pin;
- putreg32(regval, base + TIVA_GPIO_IM_OFFSET);
+ uint32_t isset = 0;
+ uint32_t ibeset = 0;
+ uint32_t ievset = 0;
+ uint32_t isclr = 0;
+ uint32_t ibeclr = 0;
+ uint32_t ievclr = 0;
- /* "The GPIOICR register is the interrupt clear register. Writing a 1 to a bit
- * in this register clears the corresponding interrupt edge detection logic
- * register. Writing a 0 has no effect."
- */
+ /* Mask and clear the GPIO interrupt */
- regval = getreg32(base + TIVA_GPIO_ICR_OFFSET);
- regval |= pin;
- putreg32(regval, base + TIVA_GPIO_ICR_OFFSET);
+ tiva_gpioirqdisable(port, pin);
+ tiva_gpioirqclear(port, pin);
- /* Assume rising edge */
-
- isset = 0; /* Not level sensed */
- isclr = pin;
- ibeset = 0; /* Single edge */
- ibeclr = pin;
- iveset = pin; /* Rising edge or high levels*/
- iveclr = 0;
-
- /* Then handle according to the selected interrupt type */
+ /* handle according to the selected interrupt type */
switch (inttype)
{
- case 0: /* Interrupt on falling edge */
+ case GPIO_INT_FALLINGEDGE:
{
- iveset = 0; /* Falling edge or low levels*/
- iveclr = pin;
+ isset = pin;
+ ibeclr = pin;
+ ievset = pin;
}
break;
- case 1: /* Interrupt on rising edge */
- default:
+ case GPIO_INT_RISINGEDGE:
+ {
+ isclr = pin;
+ ibeclr = pin;
+ ievset = pin;
+ }
break;
- case 2: /* Interrupt on both edges */
+ case GPIO_INT_BOTHEDGES:
{
- ibeset = pin; /* Both edges */
- ibeclr = 0;
+ isclr = pin;
+ ibeset = pin;
+ ievclr = pin;
}
break;
- case 3: /* Interrupt on low level */
+ case GPIO_INT_LOWLEVEL:
{
- isset = pin; /* Level sensed */
- isclr = 0;
- iveset = 0; /* Falling edge or low levels*/
- iveclr = pin;
+ isset = pin;
+ ibeclr = pin;
+ ievclr = pin;
}
break;
- case 4: /* Interrupt on high level */
+ case GPIO_INT_HIGHLEVEL:
{
- isset = pin; /* Level sensed */
- isclr = 0;
+ isset = pin;
+ ibeclr = pin;
+ ievset = pin;
}
break;
- }
- /* "The GPIO IS register is the interrupt sense register. Bits set to
- * 1 in GPIOIS configure the corresponding pins to detect levels, while
- * bits set to 0 configure the pins to detect edges. All bits are cleared
- * by a reset.
- */
-
- regval = getreg32(base + TIVA_GPIO_IS_OFFSET);
- regval &= isclr;
- regval |= isset;
- putreg32(regval, base + TIVA_GPIO_IS_OFFSET);
+ default:
+ break;
+ }
/* "The GPIO IBE register is the interrupt both-edges register. When the
* corresponding bit in the GPIO Interrupt Sense (GPIO IS) register ... is
@@ -737,10 +692,15 @@ static inline void tiva_interrupt(uint32_t base, uint32_t pin, uint32_t cfgset)
* are cleared by a reset.
*/
- regval = getreg32(base + TIVA_GPIO_IBE_OFFSET);
- regval &= ibeclr;
- regval |= ibeset;
- putreg32(regval, base + TIVA_GPIO_IBE_OFFSET);
+ modifyreg32(base + TIVA_GPIO_IBE_OFFSET, ibeclr, ibeset);
+
+ /* "The GPIO IS register is the interrupt sense register. Bits set to
+ * 1 in GPIOIS configure the corresponding pins to detect levels, while
+ * bits set to 0 configure the pins to detect edges. All bits are cleared
+ * by a reset.
+ */
+
+ modifyreg32(base + TIVA_GPIO_IS_OFFSET, isclr, isset);
/* "The GPIOIEV register is the interrupt event register. Bits set to
* High in GPIO IEV configure the corresponding pin to detect rising edges
@@ -750,10 +710,18 @@ static inline void tiva_interrupt(uint32_t base, uint32_t pin, uint32_t cfgset)
* value in GPIOIS. All bits are cleared by a reset.
*/
- regval = getreg32(base + TIVA_GPIO_IEV_OFFSET);
- regval &= iveclr;
- regval |= iveset;
- putreg32(regval, base + TIVA_GPIO_IEV_OFFSET);
+ modifyreg32(base + TIVA_GPIO_IEV_OFFSET, ievclr, ievset);
+
+#ifdef CONFIG_DEBUG_GPIO
+ uint32_t regval;
+ vdbg("reg expected actual: [interrupt type=%d]\n", inttype);
+ regval = (getreg32(base+TIVA_GPIO_IS_OFFSET) & pin) ? pin : 0;
+ vdbg("IS 0x%08x 0x%08x\n", isset, regval);
+ regval = (getreg32(base+TIVA_GPIO_IBE_OFFSET) & pin) ? pin : 0;
+ vdbg("IBE 0x%08x 0x%08x\n", ibeset, regval);
+ regval = (getreg32(base+TIVA_GPIO_IEV_OFFSET) & pin) ? pin : 0;
+ vdbg("IEV 0x%08x 0x%08x\n", ievset, regval);
+#endif
}
/****************************************************************************
@@ -766,7 +734,7 @@ static inline void tiva_interrupt(uint32_t base, uint32_t pin, uint32_t cfgset)
#if defined(LM4F) || defined(TM4C)
static inline void tiva_portcontrol(uint32_t base, uint32_t pinno,
- uint32_t cfgset,
+ uint32_t pinset,
const struct gpio_func_s *func)
{
uint32_t alt = 0;
@@ -781,7 +749,7 @@ static inline void tiva_portcontrol(uint32_t base, uint32_t pinno,
* configuration.
*/
- alt = (cfgset & GPIO_ALT_MASK) >> GPIO_ALT_SHIFT;
+ alt = (pinset & GPIO_ALT_MASK) >> GPIO_ALT_SHIFT;
}
/* Set the alternate function in the port control register */
@@ -808,7 +776,7 @@ static inline void tiva_portcontrol(uint32_t base, uint32_t pinno,
*
****************************************************************************/
-int tiva_configgpio(uint32_t cfgset)
+int tiva_configgpio(uint32_t pinset)
{
irqstate_t flags;
unsigned int func;
@@ -819,9 +787,9 @@ int tiva_configgpio(uint32_t cfgset)
/* Decode the basics */
- func = (cfgset & GPIO_FUNC_MASK) >> GPIO_FUNC_SHIFT;
- port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
- pinno = (cfgset & GPIO_PIN_MASK);
+ func = (pinset & GPIO_FUNC_MASK) >> GPIO_FUNC_SHIFT;
+ port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
+ pinno = (pinset & GPIO_PIN_MASK);
pin = (1 << pinno);
DEBUGASSERT(func <= GPIO_FUNC_MAX);
@@ -853,33 +821,33 @@ int tiva_configgpio(uint32_t cfgset)
*/
tiva_gpiofunc(base, pinno, &g_funcbits[0]);
- tiva_portcontrol(base, pinno, cfgset, &g_funcbits[0]);
+ tiva_portcontrol(base, pinno, pinset, &g_funcbits[0]);
/* Then set up pad strengths and pull-ups. These setups should be done before
* setting up the function because some function settings will over-ride these
* user options.
*/
- tiva_gpiopadstrength(base, pin, cfgset);
- tiva_gpiopadtype(base, pin, cfgset);
+ tiva_gpiopadstrength(base, pin, pinset);
+ tiva_gpiopadtype(base, pin, pinset);
/* Then set up the real pin function */
tiva_gpiofunc(base, pinno, &g_funcbits[func]);
- tiva_portcontrol(base, pinno, cfgset, &g_funcbits[func]);
+ tiva_portcontrol(base, pinno, pinset, &g_funcbits[func]);
/* Special case GPIO digital output pins */
- if (func == 1 || func == 3)
+ if (func == 1 || func == 3 || func == 5)
{
- tiva_initoutput(cfgset);
+ tiva_initoutput(pinset);
}
/* Special setup for interrupt GPIO pins */
else if (func == 7)
{
- tiva_interrupt(base, pin, cfgset);
+ tiva_interrupt(pinset);
}
irqrestore(flags);
@@ -976,11 +944,13 @@ void tiva_gpio_lockport(uint32_t pinset, bool lock)
unsigned int port;
unsigned int pinno;
uintptr_t base;
+ uint32_t pinmask;
/* Decode the basics */
- port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
- pinno = (pinset & GPIO_PIN_MASK);
+ port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
+ pinno = (pinset & GPIO_PIN_MASK);
+ pinmask = 1 << pinno;
/* Get the base address associated with the GPIO port */
@@ -994,14 +964,20 @@ void tiva_gpio_lockport(uint32_t pinset, bool lock)
if (lock)
{
- modifyreg32(base + TIVA_GPIO_CR_OFFSET, (1 << pinno), 0);
+#ifdef CONFIG_DEBUG_GPIO
+ vdbg(" locking port=%d pin=%d\n", port, pinno);
+#endif
+ modifyreg32(base + TIVA_GPIO_CR_OFFSET, pinmask, 0);
}
else
{
- modifyreg32(base + TIVA_GPIO_CR_OFFSET, 0, (1 << pinno));
+#ifdef CONFIG_DEBUG_GPIO
+ vdbg("unlocking port=%d pin=%d\n", port, pinno);
+#endif
+ modifyreg32(base + TIVA_GPIO_CR_OFFSET, 0, pinmask);
}
- /* Restrict acess to the TIVA_GPIO_CR_OFFSET register */
+ /* Restrict access to the TIVA_GPIO_CR_OFFSET register */
modifyreg32(base + TIVA_GPIO_LOCK_OFFSET, GPIO_LOCK_UNLOCK, GPIO_LOCK_LOCKED);
}
diff --git a/nuttx/arch/arm/src/tiva/tiva_gpio.h b/nuttx/arch/arm/src/tiva/tiva_gpio.h
index 37524747d..b36be3d08 100644
--- a/nuttx/arch/arm/src/tiva/tiva_gpio.h
+++ b/nuttx/arch/arm/src/tiva/tiva_gpio.h
@@ -1,9 +1,11 @@
-/************************************************************************************
+/****************************************************************************
* arch/arm/src/tiva/tiva_gpio.h
*
- * Copyright (C) 2009-2010, 2013-2014 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2009-2010, 2013-2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
+ * With modifications from Calvin Maguranis <calvin.maguranis@trd2inc.com>
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -31,14 +33,14 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
- ************************************************************************************/
+ ****************************************************************************/
#ifndef __ARCH_ARM_SRC_TIVA_TIVA_GPIO_H
#define __ARCH_ARM_SRC_TIVA_TIVA_GPIO_H
-/************************************************************************************
+/****************************************************************************
* Included Files
- ************************************************************************************/
+ ****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/compiler.h>
@@ -51,9 +53,129 @@
#include "up_internal.h"
#include "chip.h"
-/************************************************************************************
+/****************************************************************************
* Pre-processor Definitions
- ************************************************************************************/
+ ****************************************************************************/
+
+/* Debug ********************************************************************/
+
+#ifndef CONFIG_DEBUG
+# undef CONFIG_DEBUG_GPIO
+#endif
+
+#if defined(CONFIG_ARCH_CHIP_LM3S) || defined(CONFIG_ARCH_CHIP_LM4F) || \
+ defined(CONFIG_ARCH_CHIP_CC3200)
+
+ /* I don't believe that any of these families support interrupts on port J. Many
+ * do not support interrupts on port H either.
+ */
+
+# undef CONFIG_TIVA_GPIOJ_IRQS
+
+#elif defined(CONFIG_ARCH_CHIP_TM4C)
+
+/* The TM4C123GH6PMI supports ports A-F of which any can support interrupts */
+
+# if defined(CONFIG_ARCH_CHIP_TM4C123GH6PMI)
+# undef CONFIG_TIVA_GPIOP_IRQS /* P-Q */
+# undef CONFIG_TIVA_GPIOQ_IRQS
+
+/* The TM4C123GH6PGE supports interrupts only on port P */
+
+# elif defined(CONFIG_ARCH_CHIP_TM4C123GH6PGE)
+# undef CONFIG_TIVA_GPIOA_IRQS /* A-F */
+# undef CONFIG_TIVA_GPIOB_IRQS
+# undef CONFIG_TIVA_GPIOC_IRQS
+# undef CONFIG_TIVA_GPIOD_IRQS
+# undef CONFIG_TIVA_GPIOE_IRQS
+# undef CONFIG_TIVA_GPIOF_IRQS
+
+# undef CONFIG_TIVA_GPIOQ_IRQS /* Q */
+
+/* The TM4C123GH6ZRB and the TM4C129x support interrupts only on ports P and Q. */
+
+# else
+# undef CONFIG_TIVA_GPIOA_IRQS /* A-F */
+# undef CONFIG_TIVA_GPIOB_IRQS
+# undef CONFIG_TIVA_GPIOC_IRQS
+# undef CONFIG_TIVA_GPIOD_IRQS
+# undef CONFIG_TIVA_GPIOE_IRQS
+# undef CONFIG_TIVA_GPIOF_IRQS
+
+# endif
+
+/* No supported architecture supports interrupts on ports G-N or R-T */
+
+# undef CONFIG_TIVA_GPIOG_IRQS /* G-N */
+# undef CONFIG_TIVA_GPIOH_IRQS
+# undef CONFIG_TIVA_GPIOJ_IRQS
+# undef CONFIG_TIVA_GPIOK_IRQS
+# undef CONFIG_TIVA_GPIOL_IRQS
+# undef CONFIG_TIVA_GPIOM_IRQS
+# undef CONFIG_TIVA_GPION_IRQS
+
+# undef CONFIG_TIVA_GPIOR_IRQS /* R-T */
+# undef CONFIG_TIVA_GPIOS_IRQS
+# undef CONFIG_TIVA_GPIOT_IRQS
+
+#endif
+
+/* Mark GPIO interrupts as disabled for non-existent GPIO ports. */
+
+#if TIVA_NPORTS < 1
+# undef CONFIG_TIVA_GPIOA_IRQS
+#endif
+#if TIVA_NPORTS < 2
+# undef CONFIG_TIVA_GPIOB_IRQS
+#endif
+#if TIVA_NPORTS < 3
+# undef CONFIG_TIVA_GPIOC_IRQS
+#endif
+#if TIVA_NPORTS < 4
+# undef CONFIG_TIVA_GPIOD_IRQS
+#endif
+#if TIVA_NPORTS < 5
+# undef CONFIG_TIVA_GPIOE_IRQS
+#endif
+#if TIVA_NPORTS < 6
+# undef CONFIG_TIVA_GPIOF_IRQS
+#endif
+#if TIVA_NPORTS < 7
+# undef CONFIG_TIVA_GPIOG_IRQS
+#endif
+#if TIVA_NPORTS < 8
+# undef CONFIG_TIVA_GPIOH_IRQS
+#endif
+#if TIVA_NPORTS < 9
+# undef CONFIG_TIVA_GPIOJ_IRQS
+#endif
+#if TIVA_NPORTS < 10
+# undef CONFIG_TIVA_GPIOK_IRQS
+#endif
+#if TIVA_NPORTS < 11
+# undef CONFIG_TIVA_GPIOL_IRQS
+#endif
+#if TIVA_NPORTS < 12
+# undef CONFIG_TIVA_GPIOM_IRQS
+#endif
+#if TIVA_NPORTS < 13
+# undef CONFIG_TIVA_GPION_IRQS
+#endif
+#if TIVA_NPORTS < 14
+# undef CONFIG_TIVA_GPIOP_IRQS
+#endif
+#if TIVA_NPORTS < 15
+# undef CONFIG_TIVA_GPIOQ_IRQS
+#endif
+#if TIVA_NPORTS < 16
+# undef CONFIG_TIVA_GPIOQ_IRQS
+#endif
+#if TIVA_NPORTS < 17
+# undef CONFIG_TIVA_GPIOQ_IRQS
+#endif
+#if TIVA_NPORTS < 18
+# undef CONFIG_TIVA_GPIOQ_IRQS
+#endif
/* Bit-encoded input to tiva_configgpio() *******************************************/
@@ -200,68 +322,68 @@
# define GPIO_PIN_6 (6 << GPIO_PIN_SHIFT)
# define GPIO_PIN_7 (7 << GPIO_PIN_SHIFT)
-/************************************************************************************
+/****************************************************************************
* Public Types
- ************************************************************************************/
+ ****************************************************************************/
-/************************************************************************************
+/****************************************************************************
* Inline Functions
- ************************************************************************************/
+ ****************************************************************************/
#ifndef __ASSEMBLY__
-/************************************************************************************
+/****************************************************************************
* Public Data
- ************************************************************************************/
+ ****************************************************************************/
#if defined(__cplusplus)
extern "C"
{
#endif
-/************************************************************************************
+/****************************************************************************
* Public Function Prototypes
- ************************************************************************************/
+ ****************************************************************************/
uintptr_t tiva_gpiobaseaddress(unsigned int port);
-/************************************************************************************
+/****************************************************************************
* Name: tiva_configgpio
*
* Description:
* Configure a GPIO pin based on bit-encoded description of the pin.
*
- ************************************************************************************/
+ ****************************************************************************/
-int tiva_configgpio(uint32_t cfgset);
+int tiva_configgpio(uint32_t pinset);
-/************************************************************************************
+/****************************************************************************
* Name: tiva_gpiowrite
*
* Description:
* Write one or zero to the selected GPIO pin
*
- ************************************************************************************/
+ ****************************************************************************/
void tiva_gpiowrite(uint32_t pinset, bool value);
-/************************************************************************************
+/****************************************************************************
* Name: tiva_gpioread
*
* Description:
* Read one or zero from the selected GPIO pin
*
- ************************************************************************************/
+ ****************************************************************************/
bool tiva_gpioread(uint32_t pinset);
-/************************************************************************************
+/****************************************************************************
* Function: tiva_dumpgpio
*
* Description:
* Dump all GPIO registers associated with the provided base address
*
- ************************************************************************************/
+ ****************************************************************************/
int tiva_dumpgpio(uint32_t pinset, const char *msg);
@@ -276,14 +398,18 @@ int tiva_dumpgpio(uint32_t pinset, const char *msg);
void tiva_gpio_lockport(uint32_t pinset, bool lock);
-# ifdef CONFIG_TIVA_GPIO_IRQS
-/************************************************************************************
+#ifdef CONFIG_DEBUG_GPIO
+void tiva_gpio_dumpconfig(uint32_t pinset);
+#endif
+
+#ifdef CONFIG_TIVA_GPIO_IRQS
+/****************************************************************************
* Name: gpio_irqinitialize
*
* Description:
* Initialize all vectors to the unexpected interrupt handler
*
- ************************************************************************************/
+ ****************************************************************************/
int weak_function tiva_gpioirqinitialize(void);
@@ -291,34 +417,69 @@ int weak_function tiva_gpioirqinitialize(void);
* Name: tiva_gpioirqattach
*
* Description:
- * Attach the interrupt handler 'isr' to the GPIO IRQ 'irq'
+ * Attach a GPIO interrupt to the provided 'isr'
+ *
+ * Returns:
+ * oldhandler - the old interrupt handler assigned to this pin.
*
****************************************************************************/
-int tiva_gpioirqattach(int irq, xcpt_t isr);
-# define tiva_gpioirqdetach(isr) tiva_gpioirqattach(isr, NULL)
+xcpt_t tiva_gpioirqattach(uint32_t pinset, xcpt_t isr);
+# define tiva_gpioirqdetach(pinset) tiva_gpioirqattach(pinset, NULL)
+
+/****************************************************************************
+ * Name: tiva_gpioportirqattach
+ *
+ * Description:
+ * Attach 'isr' to the GPIO port. Only use this if you want to handle
+ * the entire ports interrupts explicitly.
+ *
+ ****************************************************************************/
+
+void tiva_gpioportirqattach(uint8_t port, xcpt_t isr);
+# define tiva_gpioportirqdetach(port) tiva_gpioportirqattach(port, NULL)
/****************************************************************************
* Name: tiva_gpioirqenable
*
* Description:
- * Enable the GPIO IRQ specified by 'irq'
+ * Enable the GPIO port IRQ
*
****************************************************************************/
-void tiva_gpioirqenable(int irq);
+void tiva_gpioirqenable(uint8_t port, uint8_t pin);
/****************************************************************************
* Name: tiva_gpioirqdisable
*
* Description:
- * Disable the GPIO IRQ specified by 'irq'
+ * Disable the GPIO port IRQ
*
****************************************************************************/
-void tiva_gpioirqdisable(int irq);
-# endif
+void tiva_gpioirqdisable(uint8_t port, uint8_t pin);
+
+/****************************************************************************
+ * Name: tiva_gpioirqstatus
+ *
+ * Description:
+ * Returns raw or masked interrupt status.
+ *
+ ****************************************************************************/
+
+uint32_t tiva_gpioirqstatus(uint8_t port, bool masked);
+
+/****************************************************************************
+ * Name: tiva_gpioirqclear
+ *
+ * Description:
+ * Clears the interrupt status of the input base
+ *
+ ****************************************************************************/
+
+void tiva_gpioirqclear(uint8_t port, uint32_t pinmask);
+#endif /* CONFIG_TIVA_GPIO_IRQS */
#if defined(__cplusplus)
}
diff --git a/nuttx/arch/arm/src/tiva/tiva_gpioirq.c b/nuttx/arch/arm/src/tiva/tiva_gpioirq.c
index 937c7c6d1..3f7f23c48 100644
--- a/nuttx/arch/arm/src/tiva/tiva_gpioirq.c
+++ b/nuttx/arch/arm/src/tiva/tiva_gpioirq.c
@@ -1,7 +1,7 @@
/****************************************************************************
* arch/arm/src/tiva/tiva_gpioirq.c
*
- * Copyright (C) 2009-2010, 2012, 2014 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2009-2010, 2012, 2014-2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -38,6 +38,8 @@
****************************************************************************/
#include <nuttx/config.h>
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
#include <stdint.h>
#include <string.h>
@@ -45,23 +47,33 @@
#include <debug.h>
#include <arch/irq.h>
+#include <arch/board/board.h>
+#include "chip.h"
+
+#include "up_internal.h"
#include "up_arch.h"
#include "irq/irq.h"
#include "tiva_gpio.h"
+#ifdef CONFIG_TIVA_GPIO_IRQS
+
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
+#define TIVA_NPINS 8
+#define TIVA_NIRQ_PINS (TIVA_NPORTS * TIVA_NPINS)
+#define TIVA_GPIO_IRQ_IDX(port,pin) ((port*TIVA_NPINS)+(pin))
+
/****************************************************************************
* Private Data
****************************************************************************/
-/* A table of handlers for each GPIO interrupt */
+/* A table of handlers for each GPIO port interrupt */
-static FAR xcpt_t g_gpioirqvector[NR_GPIO_IRQS];
+static FAR xcpt_t g_gpioportirqvector[TIVA_NIRQ_PINS];
/****************************************************************************
* Public Data
@@ -72,171 +84,457 @@ static FAR xcpt_t g_gpioirqvector[NR_GPIO_IRQS];
****************************************************************************/
/****************************************************************************
- * Name: tiva_gpiohandler
+ * Name: gpioport2irq
*
* Description:
- * Handle interrupts on each enabled GPIO port
+ * Translates from GPIO port to GPIO IRQ.
*
****************************************************************************/
-static int tiva_gpiohandler(uint32_t regbase, int irqbase, void *context)
+static int gpioport2irq(uint8_t port)
{
- uint32_t mis;
- int irq;
- int pin;
-
- /* Handle each pending GPIO interrupt. "The GPIO MIS register is the masked
- * interrupt status register. Bits read High in GPIO MIS reflect the status
- * of input lines triggering an interrupt. Bits read as Low indicate that
- * either no interrupt has been generated, or the interrupt is masked."
- */
+ int irq = -1;
+
+ switch (port)
+ {
+#ifdef CONFIG_TIVA_GPIOA_IRQS
+ case (GPIO_PORTA >> GPIO_PORT_SHIFT):
+ {
+ irq = TIVA_IRQ_GPIOA;
+ }
+ break;
+#endif
+
+#ifdef CONFIG_TIVA_GPIOB_IRQS
+ case (GPIO_PORTB >> GPIO_PORT_SHIFT):
+ {
+ irq = TIVA_IRQ_GPIOB;
+ }
+ break;
+#endif
+
+#ifdef CONFIG_TIVA_GPIOC_IRQS
+ case (GPIO_PORTC >> GPIO_PORT_SHIFT):
+ {
+ irq = TIVA_IRQ_GPIOC;
+ }
+ break;
+#endif
+
+#ifdef CONFIG_TIVA_GPIOD_IRQS
+ case (GPIO_PORTD >> GPIO_PORT_SHIFT):
+ {
+ irq = TIVA_IRQ_GPIOD;
+ }
+ break;
+#endif
+
+#ifdef CONFIG_TIVA_GPIOE_IRQS
+ case (GPIO_PORTE >> GPIO_PORT_SHIFT):
+ {
+ irq = TIVA_IRQ_GPIOE;
+ }
+ break;
+#endif
+
+#ifdef CONFIG_TIVA_GPIOF_IRQS
+ case (GPIO_PORTF >> GPIO_PORT_SHIFT):
+ {
+ irq = TIVA_IRQ_GPIOF;
+ }
+ break;
+#endif
+
+#ifdef CONFIG_TIVA_GPIOG_IRQS
+ case (GPIO_PORTG >> GPIO_PORT_SHIFT):
+ {
+ irq = TIVA_IRQ_GPIOG;
+ }
+ break;
+#endif
+
+#ifdef CONFIG_TIVA_GPIOH_IRQS
+ case (GPIO_PORTH >> GPIO_PORT_SHIFT):
+ {
+ irq = TIVA_IRQ_GPIOH;
+ }
+ break;
+#endif
+
+#ifdef CONFIG_TIVA_GPIOJ_IRQS
+ case (GPIO_PORTJ >> GPIO_PORT_SHIFT):
+ {
+ irq = TIVA_IRQ_GPIOJ;
+ }
+ break;
+#endif
+
+#ifdef CONFIG_TIVA_GPIOK_IRQS
+ case (GPIO_PORTK >> GPIO_PORT_SHIFT):
+ {
+ irq = TIVA_IRQ_GPIOK;
+ }
+ break;
+#endif
+
+#ifdef CONFIG_TIVA_GPIOL_IRQS
+ case (GPIO_PORTL >> GPIO_PORT_SHIFT):
+ {
+ irq = TIVA_IRQ_GPIOL;
+ }
+ break;
+#endif
- mis = getreg32(regbase + TIVA_GPIO_MIS_OFFSET) & 0xff;
+#ifdef CONFIG_TIVA_GPIOM_IRQS
+ case (GPIO_PORTM >> GPIO_PORT_SHIFT):
+ {
+ irq = TIVA_IRQ_GPIOM;
+ }
+ break;
+#endif
+
+#ifdef CONFIG_TIVA_GPION_IRQS
+ case (GPIO_PORTN >> GPIO_PORT_SHIFT):
+ {
+ irq = TIVA_IRQ_GPION;
+ }
+ break;
+#endif
+#ifdef CONFIG_TIVA_GPIOP_IRQS
+ case (GPIO_PORTP >> GPIO_PORT_SHIFT):
+ {
+ irq = TIVA_IRQ_GPIOP;
+ }
+ break;
+#endif
+
+#ifdef CONFIG_TIVA_GPIOQ_IRQS
+ case (GPIO_PORTQ >> GPIO_PORT_SHIFT):
+ {
+ irq = TIVA_IRQ_GPIOQ;
+ }
+ break;
+#endif
+
+#ifdef CONFIG_TIVA_GPIOR_IRQS
+ case (GPIO_PORTR >> GPIO_PORT_SHIFT):
+ {
+ irq = TIVA_IRQ_GPIOR;
+ }
+ break;
+#endif
+
+#ifdef CONFIG_TIVA_GPIOS_IRQS
+ case (GPIO_PORTS >> GPIO_PORT_SHIFT):
+ {
+ irq = TIVA_IRQ_GPIOS;
+ }
+ break;
+#endif
+ }
+
+ return irq;
+}
+
+/****************************************************************************
+ * Name: tiva_gpioirqstatus
+ *
+ * Description:
+ * Returns raw or masked interrupt status.
+ *
+ ****************************************************************************/
+
+uint32_t tiva_gpioirqstatus(uint8_t port, bool masked)
+{
+ uintptr_t base = tiva_gpiobaseaddress(port);
+
+ if (masked)
+ {
+ return getreg32(base + TIVA_GPIO_MIS_OFFSET);
+ }
+ else
+ {
+ return getreg32(base + TIVA_GPIO_RIS_OFFSET);
+ }
+}
+
+/****************************************************************************
+ * Name: tiva_gpioirqclear
+ *
+ * Description:
+ * Clears the interrupt status of the input base
+ *
+ ****************************************************************************/
+
+void tiva_gpioirqclear(uint8_t port, uint32_t pinmask)
+{
+ uintptr_t base = tiva_gpiobaseaddress(port);
- /* Clear all GPIO interrupts that we are going to process. "The GPIO ICR
- * register is the interrupt clear register. Writing a 1 to a bit in this
- * register clears the corresponding interrupt edge detection logic register.
- * Writing a 0 has no effect."
+ /* "The GPIOICR register is the interrupt clear register. Writing a 1 to a bit
+ * in this register clears the corresponding interrupt edge detection logic
+ * register. Writing a 0 has no effect."
*/
- putreg32(mis, regbase + TIVA_GPIO_ICR_OFFSET);
+ modifyreg32(base + TIVA_GPIO_ICR_OFFSET, 0, pinmask);
+}
+
+/****************************************************************************
+ * Name: tiva_gpioporthandler
+ *
+ * Description:
+ * Handle interrupts on each enabled GPIO port
+ *
+ ****************************************************************************/
+
+static int tiva_gpioporthandler(uint8_t port, void *context)
+{
+
+ int irq = gpioport2irq(port); /* GPIO port interrupt vector */
+ uint32_t mis = tiva_gpioirqstatus(port, true); /* Masked Interrupt Status */
+ uint8_t pin; /* Pin number */
+
+ tiva_gpioirqclear(port, 0xff);
+ llvdbg("mis=0b%08b\n", mis & 0xff);
/* Now process each IRQ pending in the MIS */
- for (pin = 0; pin < 8 && mis != 0; pin++, mis >>= 1)
+ if (mis != 0)
{
- if ((mis & 1) != 0)
+ for (pin = 0; pin < TIVA_NPINS; ++pin)
{
- irq = irqbase + pin;
- g_gpioirqvector[irq - NR_IRQS](irq, context);
+ if (((mis >> pin) & 1) != 0)
+ {
+ llvdbg("port=%d pin=%d irq=%p index=%d\n",
+ port, pin,
+ g_gpioportirqvector[TIVA_GPIO_IRQ_IDX(port, pin)],
+ TIVA_GPIO_IRQ_IDX(port, pin));
+
+ g_gpioportirqvector[TIVA_GPIO_IRQ_IDX(port, pin)](irq, context);
+ }
}
}
+
return OK;
}
#ifdef CONFIG_TIVA_GPIOA_IRQS
static int tiva_gpioahandler(int irq, FAR void *context)
{
- return tiva_gpiohandler(TIVA_GPIOA_BASE, TIVA_IRQ_GPIOA_0, context);
+ irqstate_t flags;
+ flags = irqsave();
+ up_disable_irq(irq);
+ int ret = tiva_gpioporthandler((GPIO_PORTA >> GPIO_PORT_SHIFT), context);
+ up_enable_irq(irq);
+ irqrestore(flags);
+ return ret;
}
#endif
#ifdef CONFIG_TIVA_GPIOB_IRQS
static int tiva_gpiobhandler(int irq, FAR void *context)
{
- return tiva_gpiohandler(TIVA_GPIOB_BASE, TIVA_IRQ_GPIOB_0, context);
+ irqstate_t flags;
+ flags = irqsave();
+ up_disable_irq(irq);
+ int ret = tiva_gpioporthandler((GPIO_PORTB >> GPIO_PORT_SHIFT), context);
+ up_enable_irq(irq);
+ irqrestore(flags);
+ return ret;
}
#endif
#ifdef CONFIG_TIVA_GPIOC_IRQS
static int tiva_gpiochandler(int irq, FAR void *context)
{
- return tiva_gpiohandler(TIVA_GPIOC_BASE, TIVA_IRQ_GPIOC_0, context);
+ irqstate_t flags;
+ flags = irqsave();
+ up_disable_irq(irq);
+ int ret = tiva_gpioporthandler((GPIO_PORTC >> GPIO_PORT_SHIFT), context);
+ up_enable_irq(irq);
+ irqrestore(flags);
+ return ret;
}
#endif
#ifdef CONFIG_TIVA_GPIOD_IRQS
static int tiva_gpiodhandler(int irq, FAR void *context)
{
- return tiva_gpiohandler(TIVA_GPIOD_BASE, TIVA_IRQ_GPIOD_0, context);
+ irqstate_t flags;
+ flags = irqsave();
+ up_disable_irq(irq);
+ int ret = tiva_gpioporthandler((GPIO_PORTD >> GPIO_PORT_SHIFT), context);
+ up_enable_irq(irq);
+ irqrestore(flags);
+ return ret;
}
#endif
#ifdef CONFIG_TIVA_GPIOE_IRQS
static int tiva_gpioehandler(int irq, FAR void *context)
{
- return tiva_gpiohandler(TIVA_GPIOE_BASE, TIVA_IRQ_GPIOE_0, context);
+ irqstate_t flags;
+ flags = irqsave();
+ up_disable_irq(irq);
+ int ret = tiva_gpioporthandler((GPIO_PORTE >> GPIO_PORT_SHIFT), context);
+ up_enable_irq(irq);
+ irqrestore(flags);
+ return ret;
}
#endif
#ifdef CONFIG_TIVA_GPIOF_IRQS
static int tiva_gpiofhandler(int irq, FAR void *context)
{
- return tiva_gpiohandler(TIVA_GPIOF_BASE, TIVA_IRQ_GPIOF_0, context);
+ irqstate_t flags;
+ flags = irqsave();
+ up_disable_irq(irq);
+ int ret = tiva_gpioporthandler((GPIO_PORTF >> GPIO_PORT_SHIFT), context);
+ up_enable_irq(irq);
+ irqrestore(flags);
+ return ret;
}
#endif
#ifdef CONFIG_TIVA_GPIOG_IRQS
static int tiva_gpioghandler(int irq, FAR void *context)
{
- return tiva_gpiohandler(TIVA_GPIOG_BASE, TIVA_IRQ_GPIOG_0, context);
+ irqstate_t flags;
+ flags = irqsave();
+ up_disable_irq(irq);
+ int ret = tiva_gpioporthandler((GPIO_PORTG >> GPIO_PORT_SHIFT), context);
+ up_enable_irq(irq);
+ irqrestore(flags);
+ return ret;
}
#endif
#ifdef CONFIG_TIVA_GPIOH_IRQS
static int tiva_gpiohhandler(int irq, FAR void *context)
{
- return tiva_gpiohandler(TIVA_GPIOH_BASE, TIVA_IRQ_GPIOH_0, context);
+ irqstate_t flags;
+ flags = irqsave();
+ up_disable_irq(irq);
+ int ret = tiva_gpioporthandler((GPIO_PORTH >> GPIO_PORT_SHIFT), context);
+ up_enable_irq(irq);
+ irqrestore(flags);
+ return ret;
}
#endif
#ifdef CONFIG_TIVA_GPIOJ_IRQS
static int tiva_gpiojhandler(int irq, FAR void *context)
{
- return tiva_gpiohandler(TIVA_GPIOJ_BASE, TIVA_IRQ_GPIOJ_0, context);
+ irqstate_t flags;
+ flags = irqsave();
+ up_disable_irq(irq);
+ int ret = tiva_gpioporthandler((GPIO_PORTJ >> GPIO_PORT_SHIFT), context);
+ up_enable_irq(irq);
+ irqrestore(flags);
+ return ret;
}
#endif
#ifdef CONFIG_TIVA_GPIOK_IRQS
static int tiva_gpiokhandler(int irq, FAR void *context)
{
- return tiva_gpiohandler(TIVA_GPIOK_BASE, TIVA_IRQ_GPIOK_0, context);
+ irqstate_t flags;
+ flags = irqsave();
+ up_disable_irq(irq);
+ int ret = tiva_gpioporthandler((GPIO_PORTK >> GPIO_PORT_SHIFT), context);
+ up_enable_irq(irq);
+ irqrestore(flags);
+ return ret;
}
#endif
#ifdef CONFIG_TIVA_GPIOL_IRQS
static int tiva_gpiolhandler(int irq, FAR void *context)
{
- return tiva_gpiohandler(TIVA_GPIOL_BASE, TIVA_IRQ_GPIOL_0, context);
+ irqstate_t flags;
+ flags = irqsave();
+ up_disable_irq(irq);
+ int ret = tiva_gpioporthandler((GPIO_PORTL >> GPIO_PORT_SHIFT), context);
+ up_enable_irq(irq);
+ irqrestore(flags);
+ return ret;
}
#endif
#ifdef CONFIG_TIVA_GPIOM_IRQS
static int tiva_gpiomhandler(int irq, FAR void *context)
{
- return tiva_gpiohandler(TIVA_GPIOM_BASE, TIVA_IRQ_GPIOM_0, context);
+ irqstate_t flags;
+ flags = irqsave();
+ up_disable_irq(irq);
+ int ret = tiva_gpioporthandler((GPIO_PORTM >> GPIO_PORT_SHIFT), context);
+ up_enable_irq(irq);
+ irqrestore(flags);
+ return ret;
}
#endif
#ifdef CONFIG_TIVA_GPION_IRQS
static int tiva_gpionhandler(int irq, FAR void *context)
{
- return tiva_gpiohandler(TIVA_GPION_BASE, TIVA_IRQ_GPION_0, context);
+ irqstate_t flags;
+ flags = irqsave();
+ up_disable_irq(irq);
+ int ret = tiva_gpioporthandler((GPIO_PORTN >> GPIO_PORT_SHIFT), context);
+ up_enable_irq(irq);
+ irqrestore(flags);
+ return ret;
}
#endif
#ifdef CONFIG_TIVA_GPIOP_IRQS
static int tiva_gpiophandler(int irq, FAR void *context)
{
- return tiva_gpiohandler(TIVA_GPIOP_BASE, TIVA_IRQ_GPIOP_0, context);
+ irqstate_t flags;
+ flags = irqsave();
+ up_disable_irq(irq);
+ int ret = tiva_gpioporthandler((GPIO_PORTP >> GPIO_PORT_SHIFT), context);
+ up_enable_irq(irq);
+ irqrestore(flags);
+ return ret;
}
#endif
#ifdef CONFIG_TIVA_GPIOQ_IRQS
static int tiva_gpioqhandler(int irq, FAR void *context)
{
- return tiva_gpiohandler(TIVA_GPIOQ_BASE, TIVA_IRQ_GPIOQ_0, context);
+ irqstate_t flags;
+ flags = irqsave();
+ up_disable_irq(irq);
+ int ret = tiva_gpioporthandler((GPIO_PORTQ >> GPIO_PORT_SHIFT), context);
+ up_enable_irq(irq);
+ irqrestore(flags);
+ return ret;
}
#endif
#ifdef CONFIG_TIVA_GPIOR_IRQS
static int tiva_gpiorhandler(int irq, FAR void *context)
{
- return tiva_gpiohandler(TIVA_GPIOR_BASE, TIVA_IRQ_GPIOR_0, context);
+ irqstate_t flags;
+ flags = irqsave();
+ up_disable_irq(irq);
+ int ret = tiva_gpioporthandler((GPIO_PORTR >> GPIO_PORT_SHIFT), context);
+ up_enable_irq(irq);
+ irqrestore(flags);
+ return ret;
}
#endif
#ifdef CONFIG_TIVA_GPIOS_IRQS
static int tiva_gpioshandler(int irq, FAR void *context)
{
- return tiva_gpiohandler(TIVA_GPIOS_BASE, TIVA_IRQ_GPIOS_0, context);
-}
-#endif
-
-#ifdef CONFIG_TIVA_GPIOT_IRQS
-static int tiva_gpiothandler(int irq, FAR void *context)
-{
- return tiva_gpiohandler(TIVA_GPIOT_BASE, TIVA_IRQ_GPIOT_0, context);
+ irqstate_t flags;
+ flags = irqsave();
+ up_disable_irq(irq);
+ int ret = tiva_gpioporthandler((GPIO_PORTS >> GPIO_PORT_SHIFT), context);
+ up_enable_irq(irq);
+ irqrestore(flags);
+ return ret;
}
#endif
@@ -258,11 +556,14 @@ int tiva_gpioirqinitialize(void)
/* Point all interrupt vectors to the unexpected interrupt */
- for (i = 0; i < NR_GPIO_IRQS; i++)
+ for (i = 0; i < TIVA_NIRQ_PINS; ++i)
{
- g_gpioirqvector[i] = irq_unexpected_isr;
+ g_gpioportirqvector[i] = irq_unexpected_isr;
}
+ vdbg("tiva_gpioirqinitialize isr=%d/%d irq_unexpected_isr=%p\n",
+ i, TIVA_NIRQ_PINS, irq_unexpected_isr);
+
/* Then attach each GPIO interrupt handlers and enable corresponding GPIO
* interrupts
*/
@@ -271,74 +572,86 @@ int tiva_gpioirqinitialize(void)
irq_attach(TIVA_IRQ_GPIOA, tiva_gpioahandler);
up_enable_irq(TIVA_IRQ_GPIOA);
#endif
+
#ifdef CONFIG_TIVA_GPIOB_IRQS
irq_attach(TIVA_IRQ_GPIOB, tiva_gpiobhandler);
up_enable_irq(TIVA_IRQ_GPIOB);
#endif
+
#ifdef CONFIG_TIVA_GPIOC_IRQS
irq_attach(TIVA_IRQ_GPIOC, tiva_gpiochandler);
up_enable_irq(TIVA_IRQ_GPIOC);
#endif
+
#ifdef CONFIG_TIVA_GPIOD_IRQS
irq_attach(TIVA_IRQ_GPIOD, tiva_gpiodhandler);
up_enable_irq(TIVA_IRQ_GPIOD);
#endif
+
#ifdef CONFIG_TIVA_GPIOE_IRQS
irq_attach(TIVA_IRQ_GPIOE, tiva_gpioehandler);
up_enable_irq(TIVA_IRQ_GPIOE);
#endif
+
#ifdef CONFIG_TIVA_GPIOF_IRQS
irq_attach(TIVA_IRQ_GPIOF, tiva_gpiofhandler);
up_enable_irq(TIVA_IRQ_GPIOF);
#endif
+
#ifdef CONFIG_TIVA_GPIOG_IRQS
irq_attach(TIVA_IRQ_GPIOG, tiva_gpioghandler);
up_enable_irq(TIVA_IRQ_GPIOG);
#endif
+
#ifdef CONFIG_TIVA_GPIOH_IRQS
irq_attach(TIVA_IRQ_GPIOH, tiva_gpiohhandler);
up_enable_irq(TIVA_IRQ_GPIOH);
#endif
+
#ifdef CONFIG_TIVA_GPIOJ_IRQS
irq_attach(TIVA_IRQ_GPIOJ, tiva_gpiojhandler);
up_enable_irq(TIVA_IRQ_GPIOJ);
#endif
+
#ifdef CONFIG_TIVA_GPIOK_IRQS
irq_attach(TIVA_IRQ_GPIOK, tiva_gpiokhandler);
up_enable_irq(TIVA_IRQ_GPIOK);
#endif
+
#ifdef CONFIG_TIVA_GPIOL_IRQS
irq_attach(TIVA_IRQ_GPIOL, tiva_gpiolhandler);
up_enable_irq(TIVA_IRQ_GPIOL);
#endif
+
#ifdef CONFIG_TIVA_GPIOM_IRQS
irq_attach(TIVA_IRQ_GPIOM, tiva_gpiomhandler);
up_enable_irq(TIVA_IRQ_GPIOM);
#endif
+
#ifdef CONFIG_TIVA_GPION_IRQS
irq_attach(TIVA_IRQ_GPION, tiva_gpionhandler);
up_enable_irq(TIVA_IRQ_GPION);
#endif
+
#ifdef CONFIG_TIVA_GPIOP_IRQS
irq_attach(TIVA_IRQ_GPIOP, tiva_gpiophandler);
up_enable_irq(TIVA_IRQ_GPIOP);
#endif
+
#ifdef CONFIG_TIVA_GPIOQ_IRQS
irq_attach(TIVA_IRQ_GPIOQ, tiva_gpioqhandler);
up_enable_irq(TIVA_IRQ_GPIOQ);
#endif
+
#ifdef CONFIG_TIVA_GPIOR_IRQS
irq_attach(TIVA_IRQ_GPIOR, tiva_gpiorhandler);
up_enable_irq(TIVA_IRQ_GPIOR);
#endif
+
#ifdef CONFIG_TIVA_GPIOS_IRQS
irq_attach(TIVA_IRQ_GPIOS, tiva_gpioshandler);
up_enable_irq(TIVA_IRQ_GPIOS);
#endif
-#ifdef CONFIG_TIVA_GPIOT_IRQS
- irq_attach(TIVA_IRQ_GPIOT, tiva_gpiothandler);
- up_enable_irq(TIVA_IRQ_GPIOT);
-#endif
return OK;
}
@@ -347,117 +660,143 @@ int tiva_gpioirqinitialize(void)
* Name: tiva_gpioirqattach
*
* Description:
- * Attach in GPIO interrupt to the provide 'isr'
+ * Attach in GPIO interrupt to the provided 'isr'. If isr==NULL, then the
+ * irq_unexpected_isr handler is assigned and the pin's interrupt mask is
+ * disabled to stop further interrupts. Otherwise, the new isr is linked
+ * and the pin's interrupt mask is set.
+ *
+ * Returns:
+ * oldhandler - the old interrupt handler assigned to this pin.
*
****************************************************************************/
-int tiva_gpioirqattach(int irq, xcpt_t isr)
+xcpt_t tiva_gpioirqattach(uint32_t pinset, xcpt_t isr)
{
irqstate_t flags;
- int gpioirq = irq - NR_IRQS;
- int ret = ERROR;
+ xcpt_t oldhandler = NULL;
+ uint8_t port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
+ uint8_t pinno = (pinset & GPIO_PIN_MASK);
+ uint8_t pin = 1 << pinno;
+
+ /* assign per-pin interrupt handlers */
- if ((unsigned)gpioirq < NR_GPIO_IRQS)
+ if (port < TIVA_NPORTS)
{
flags = irqsave();
+ /* store the older handler to return */
+
+ oldhandler = g_gpioportirqvector[TIVA_GPIO_IRQ_IDX(port, pinno)];
+
/* If the new ISR is NULL, then the ISR is being detached.
* In this case, disable the ISR and direct any interrupts
* to the unexpected interrupt handler.
*/
+ vdbg("assign port=%d pin=%d function=%p to idx=%d\n",
+ port, pinno, isr, TIVA_GPIO_IRQ_IDX(port, pinno));
+
if (isr == NULL)
{
-#ifndef CONFIG_ARCH_NOINTC
- tiva_gpioirqdisable(gpioirq);
-#endif
- isr = irq_unexpected_isr;
+ tiva_gpioirqdisable(port, pin);
+ g_gpioportirqvector[TIVA_GPIO_IRQ_IDX(port, pinno)] = irq_unexpected_isr;
+ }
+ else
+ {
+ g_gpioportirqvector[TIVA_GPIO_IRQ_IDX(port, pinno)] = isr;
+ tiva_gpioirqenable(port, pin);
}
- /* Save the new ISR in the table. */
-
- g_irqvector[gpioirq] = isr;
irqrestore(flags);
- ret = OK;
}
- return ret;
+
+ return oldhandler;
}
/****************************************************************************
- * Name: tiva_gpioirqenable
+ * Name: tiva_gpioportirqattach
*
* Description:
- * Enable the GPIO IRQ specified by 'irq'
+ * Attach 'isr' to the GPIO port. Only use this if you want to handle
+ * the entire ports interrupts explicitly.
*
****************************************************************************/
-void tiva_gpioirqenable(int irq)
+void tiva_gpioportirqattach(uint8_t port, xcpt_t isr)
{
irqstate_t flags;
- int gpioirq = irq - NR_IRQS;
- uintptr_t base;
- uint32_t regval;
- int pin;
+ int irq = gpioport2irq(port);
- if ((unsigned)gpioirq < NR_GPIO_IRQS)
- {
- /* Get the base address of the GPIO module associated with this IRQ */
+ /* assign port interrupt handler */
- base = tiva_gpiobaseaddress(gpioirq);
- DEBUGASSERT(base != 0);
- pin = (1 << (gpioirq & 7));
+ if (port < TIVA_NPORTS)
+ {
+ flags = irqsave();
- /* Disable the GPIO interrupt. "The GPIO IM register is the interrupt
- * mask register. Bits set to High in GPIO IM allow the corresponding
- * pins to trigger their individual interrupts and the combined GPIO INTR
- * line. Clearing a bit disables interrupt triggering on that pin. All
- * bits are cleared by a reset.
+ /* If the new ISR is NULL, then the ISR is being detached.
+ * In this case, disable the ISR and direct any interrupts
+ * to the unexpected interrupt handler.
*/
- flags = irqsave();
- regval = getreg32(base + TIVA_GPIO_IM_OFFSET);
- regval |= pin;
- putreg32(regval, base + TIVA_GPIO_IM_OFFSET);
+ vdbg("assign function=%p to port=%d\n", isr, port);
+
+ if (isr == NULL)
+ {
+ tiva_gpioirqdisable(port, 0xff);
+ irq_attach(irq, irq_unexpected_isr);
+ }
+ else
+ {
+ irq_attach(irq, isr);
+ tiva_gpioirqenable(port, 0xff);
+ }
+
irqrestore(flags);
}
}
/****************************************************************************
- * Name: tiva_gpioirqdisable
+ * Name: tiva_gpioirqenable
*
* Description:
- * Disable the GPIO IRQ specified by 'irq'
+ * Enable the GPIO port IRQ
*
****************************************************************************/
-void tiva_gpioirqdisable(int irq)
+void tiva_gpioirqenable(uint8_t port, uint8_t pin)
{
- irqstate_t flags;
- int gpioirq = irq - NR_IRQS;
- uintptr_t base;
- uint32_t regval;
- int pin;
+ uintptr_t base = tiva_gpiobaseaddress(port);
- if ((unsigned)gpioirq < NR_GPIO_IRQS)
- {
- /* Get the base address of the GPIO module associated with this IRQ */
+ /* Enable the GPIO interrupt. "The GPIO IM register is the interrupt
+ * mask register. Bits set to High in GPIO IM allow the corresponding
+ * pins to trigger their individual interrupts and the combined GPIO INTR
+ * line. Clearing a bit disables interrupt triggering on that pin. All
+ * bits are cleared by a reset.
+ */
- base = tiva_gpiobaseaddress(gpioirq);
- DEBUGASSERT(base != 0);
- pin = (1 << (gpioirq & 7));
+ modifyreg32(base + TIVA_GPIO_IM_OFFSET, 0, pin);
+}
- /* Disable the GPIO interrupt. "The GPIO IM register is the interrupt
- * mask register. Bits set to High in GPIO IM allow the corresponding
- * pins to trigger their individual interrupts and the combined GPIO INTR
- * line. Clearing a bit disables interrupt triggering on that pin. All
- * bits are cleared by a reset.
- */
+/****************************************************************************
+ * Name: tiva_gpioirqdisable
+ *
+ * Description:
+ * Disable the GPIO port IRQ
+ *
+ ****************************************************************************/
- flags = irqsave();
- regval = getreg32(base + TIVA_GPIO_IM_OFFSET);
- regval &= ~pin;
- putreg32(regval, base + TIVA_GPIO_IM_OFFSET);
- irqrestore(flags);
- }
+void tiva_gpioirqdisable(uint8_t port, uint8_t pin)
+{
+ uintptr_t base = tiva_gpiobaseaddress(port);
+
+ /* Disable the GPIO interrupt. "The GPIO IM register is the interrupt
+ * mask register. Bits set to High in GPIO IM allow the corresponding
+ * pins to trigger their individual interrupts and the combined GPIO INTR
+ * line. Clearing a bit disables interrupt triggering on that pin. All
+ * bits are cleared by a reset.
+ */
+
+ modifyreg32(base + TIVA_GPIO_IM_OFFSET, pin, 0);
}
+#endif /* CONFIG_TIVA_GPIO_IRQS */
diff --git a/nuttx/arch/arm/src/tiva/tiva_timer.h b/nuttx/arch/arm/src/tiva/tiva_timer.h
index 2c521f3a5..0f262bc73 100644
--- a/nuttx/arch/arm/src/tiva/tiva_timer.h
+++ b/nuttx/arch/arm/src/tiva/tiva_timer.h
@@ -1,7 +1,7 @@
/****************************************************************************
* arch/arm/src/tiva/tiva_timer.h
*
- * Copyright (C) 201r Gregory Nutt. All rights reserved.
+ * Copyright (C) 2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -831,7 +831,7 @@ static inline void tiva_gptm0_synchronize(uint32_t sync)
#endif
/****************************************************************************
- * Name: tiva_timer_register
+ * Name: tiva_timer_initialize
*
* Description:
* Bind the configuration timer to a timer lower half instance and
@@ -847,8 +847,7 @@ static inline void tiva_gptm0_synchronize(uint32_t sync)
* Input Parameters:
* devpath - The full path to the timer device. This should be of the
* form /dev/timer0
- * gptm - General purpose timer number
- * altlck - True: Use alternate clock source.
+ * config - 32-bit timer configuration values.
*
* Returned Values:
* Zero (OK) is returned on success; A negated errno value is returned
@@ -857,7 +856,8 @@ static inline void tiva_gptm0_synchronize(uint32_t sync)
****************************************************************************/
#ifdef CONFIG_TIMER
-int tiva_timer_register(FAR const char *devpath, int gptm, bool altclk);
+int tiva_timer_initialize(FAR const char *devpath,
+ struct tiva_gptm32config_s *config);
#endif
#endif /* __ARCH_ARM_SRC_TIVA_TIVA_TIMER_H */
diff --git a/nuttx/arch/arm/src/tiva/tiva_timerlib.c b/nuttx/arch/arm/src/tiva/tiva_timerlib.c
index 6ea3eb17b..a9f3741d8 100644
--- a/nuttx/arch/arm/src/tiva/tiva_timerlib.c
+++ b/nuttx/arch/arm/src/tiva/tiva_timerlib.c
@@ -1644,7 +1644,6 @@ TIMER_HANDLE tiva_gptm_configure(const struct tiva_gptmconfig_s *config)
case 0:
/* Enable GPTM0 clocking and power */
-
attr = &g_gptm0_attr;
priv = &g_gptm0_state;
break;
@@ -2321,9 +2320,12 @@ void tiva_timer32_setinterval(TIMER_HANDLE handle, uint32_t interval)
#endif /* CONFIG_ARCH_CHIP_TM4C129 */
bool toints;
- DEBUGASSERT(priv && priv->attr && priv->config &&
- priv->config->mode != TIMER16_MODE);
+ DEBUGASSERT(priv);
+ DEBUGASSERT(priv->attr);
+ DEBUGASSERT(priv->config);
config = (const struct tiva_gptm32config_s *)priv->config;
+
+ DEBUGASSERT(config->cmn.mode != TIMER16_MODE);
timer = &config->config;
/* Do we need to enable timeout interrupts? Interrupts are only enabled
diff --git a/nuttx/arch/arm/src/tiva/tiva_timerlow32.c b/nuttx/arch/arm/src/tiva/tiva_timerlow32.c
index 2bbf83860..a4226c62e 100644
--- a/nuttx/arch/arm/src/tiva/tiva_timerlow32.c
+++ b/nuttx/arch/arm/src/tiva/tiva_timerlow32.c
@@ -42,6 +42,7 @@
#include <sys/types.h>
#include <stdint.h>
+#include <string.h>
#include <errno.h>
#include <assert.h>
#include <debug.h>
@@ -91,7 +92,7 @@ static void tiva_timeout(struct tiva_lowerhalf_s *priv, uint32_t timeout);
/* Interrupt handling *******************************************************/
-static void tiva_handler(TIMER_HANDLE handle, void *arg, uint32_t status);
+static void tiva_timer_handler(TIMER_HANDLE handle, void *arg, uint32_t status);
/* "Lower half" driver methods **********************************************/
@@ -218,7 +219,7 @@ static void tiva_timeout(struct tiva_lowerhalf_s *priv, uint32_t timeout)
}
/****************************************************************************
- * Name: tiva_handler
+ * Name: tiva_timer_handler
*
* Description:
* 32-bit timer interrupt handler
@@ -231,7 +232,7 @@ static void tiva_timeout(struct tiva_lowerhalf_s *priv, uint32_t timeout)
*
****************************************************************************/
-static void tiva_handler(TIMER_HANDLE handle, void *arg, uint32_t status)
+static void tiva_timer_handler(TIMER_HANDLE handle, void *arg, uint32_t status)
{
struct tiva_lowerhalf_s *priv = (struct tiva_lowerhalf_s *)arg;
@@ -511,7 +512,6 @@ static tccb_t tiva_sethandler(struct timer_lowerhalf_s *lower,
static int tiva_ioctl(struct timer_lowerhalf_s *lower, int cmd,
unsigned long arg)
{
- struct tiva_lowerhalf_s *priv = (struct tiva_lowerhalf_s *)lower;
int ret = -ENOTTY;
DEBUGASSERT(priv);
@@ -525,7 +525,7 @@ static int tiva_ioctl(struct timer_lowerhalf_s *lower, int cmd,
****************************************************************************/
/****************************************************************************
- * Name: tiva_timer_register
+ * Name: tiva_timer_initialize
*
* Description:
* Bind the configuration timer to a timer lower half instance and
@@ -541,8 +541,7 @@ static int tiva_ioctl(struct timer_lowerhalf_s *lower, int cmd,
* Input Parameters:
* devpath - The full path to the timer device. This should be of the
* form /dev/timer0
- * gptm - General purpose timer number
- * altlck - True: Use alternate clock source.
+ * config - 32-bit timer configuration values.
*
* Returned Values:
* Zero (OK) is returned on success; A negated errno value is returned
@@ -550,15 +549,15 @@ static int tiva_ioctl(struct timer_lowerhalf_s *lower, int cmd,
*
****************************************************************************/
-int tiva_timer_register(FAR const char *devpath, int gptm, bool altclk)
+int tiva_timer_initialize(FAR const char *devpath,
+ struct tiva_gptm32config_s *config)
{
struct tiva_lowerhalf_s *priv;
- struct tiva_gptm32config_s *config;
void *drvr;
int ret;
+ timvdbg("\n");
DEBUGASSERT(devpath);
- timvdbg("Entry: devpath=%s\n", devpath);
/* Allocate an instance of the lower half state structure */
@@ -573,9 +572,9 @@ int tiva_timer_register(FAR const char *devpath, int gptm, bool altclk)
priv->ops = &g_timer_ops;
#ifdef CONFIG_ARCH_CHIP_TM4C129
- priv->clkin = altclk ? ALTCLK_FREQUENCY : SYSCLK_FREQUENCY;
+ priv->clkin = config->cmn.alternate ? ALTCLK_FREQUENCY : SYSCLK_FREQUENCY;
#else
- if (altclk)
+ if (config->cmn.alternate)
{
timdbg("ERROR: Alternate clock unsupported on TM4C123 architecture\n");
return -ENOMEM;
@@ -586,16 +585,9 @@ int tiva_timer_register(FAR const char *devpath, int gptm, bool altclk)
}
#endif /* CONFIG_ARCH_CHIP_TM4C129 */
- config = &priv->config;
- config->cmn.gptm = gptm;
- config->cmn.mode = TIMER32_MODE_PERIODIC;
- config->cmn.alternate = altclk;
- config->config.flags = TIMER_FLAG_COUNTUP;
-#ifdef CONFIG_TIVA_TIMER32_ADCEVENT
- config->config.flags |= TIMER_FLAG_ADCTIMEOUT;
-#endif
- config->config.handler = tiva_handler;
+ config->config.handler = tiva_timer_handler;
config->config.arg = priv;
+ memcpy(&(priv->config), config, sizeof(struct tiva_gptm32config_s));
/* Set the initial timer interval */