diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2015-03-23 09:12:52 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2015-03-23 09:12:52 -0600 |
commit | 7ae05b1a24503aea81a01305f9488c2d7be2946a (patch) | |
tree | cd53e4254c42564ba29d2d1842ee802d1d579eb1 /nuttx/arch | |
parent | 510496d8fbcf3dc46263f1971bc0756d75b1479e (diff) | |
download | px4-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
Diffstat (limited to 'nuttx/arch')
-rw-r--r-- | nuttx/arch/arm/src/tiva/Kconfig | 900 | ||||
-rw-r--r-- | nuttx/arch/arm/src/tiva/Make.defs | 3 | ||||
-rw-r--r-- | nuttx/arch/arm/src/tiva/chip/tiva_adc.h | 283 | ||||
-rw-r--r-- | nuttx/arch/arm/src/tiva/tiva_adc.c | 2820 | ||||
-rw-r--r-- | nuttx/arch/arm/src/tiva/tiva_adc.h | 594 | ||||
-rw-r--r-- | nuttx/arch/arm/src/tiva/tiva_adclib.c | 1104 | ||||
-rw-r--r-- | nuttx/arch/arm/src/tiva/tiva_adclow.c | 1030 | ||||
-rw-r--r-- | nuttx/arch/arm/src/tiva/tiva_gpio.c | 646 | ||||
-rw-r--r-- | nuttx/arch/arm/src/tiva/tiva_gpio.h | 231 | ||||
-rw-r--r-- | nuttx/arch/arm/src/tiva/tiva_gpioirq.c | 573 | ||||
-rw-r--r-- | nuttx/arch/arm/src/tiva/tiva_timer.h | 10 | ||||
-rw-r--r-- | nuttx/arch/arm/src/tiva/tiva_timerlib.c | 8 | ||||
-rw-r--r-- | nuttx/arch/arm/src/tiva/tiva_timerlow32.c | 34 |
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 */ |