ADC12

The MSPM0G3507 contains two analog-to-digital converters (ADCs) labelled ADC0 and ADC1. Both of these ADCs are both TI’s ADC12 module type. ADC12 modules are capable of converting up to 16 independent analog inputs, or channels: numbered 0-15. The modules can only be operated in a single-ended mode with no support for differential mode inputs.

An ADC12 module uses only a positive reference voltage, labeled \(V_\mathrm{R+}\), to define the voltage range for the conversion; where the negative reference voltage, \(V_\mathrm{R-}\), is always 0 V. The value for \(V_\mathrm{R+}\) is selectable among internally generated 1.4 V or 2.5 V sources; the 3.3 V power source; or can use an externally sourced reference (VREF+). Unfortunately, VREF+ is not available from the MSPM0G3507, at least in the configuration used in this class; therefore, the ADCs are limited to the values listed.

The ADC12 conversion output follows the equation:

\[N_\mathrm{ADC} = 2^{N_\mathrm{bits}} \frac{V_\mathrm{in+}-V_\mathrm{R-}}{V_\mathrm{R+}-V_\mathrm{R-}} \mathrm{~~~~~~where~~ } V_\mathrm{R-} \leq V_\mathrm{in+} < V_\mathrm{R+}\]

where \(N_\mathrm{bits}\) is the configured bit resolution of the ADC12 and \(V_\mathrm{in+}\) is the input voltage. As noted, \(V_\mathrm{R-} = 0~\mathrm{V}\); therefore, the equation can be simplified to:

\[N_\mathrm{ADC} = 2^{N_\mathrm{bits}} \frac{V_\mathrm{in+}}{V_\mathrm{R+}} \mathrm{~~~~~~where~~ } 0~\mathrm{V} \leq V_\mathrm{in+} < V_\mathrm{R+}\]

The ADC12 modules also have 12 memory locations to store conversion results, labeled as ADC_MEM_INDEX_x, where x is 0 to 11. These are configured to be associated with a single ADC input channel. It should be noted that the ADC input channel number is not related to the memory location number. For example, memory location ADC_MEM_INDEX_5 can be configured to store the conversion value of channel 2.

Sample Modes

The ADC12 can operate in four distinct modes:

  • Single-channel, single-sample: Conversion of a single channel is performed when the ADC12 receive a conversion trigger.

  • Multi-channel (sequence), single-sample: A single sample for a sequence of channels is converted when the ADC12 receives a conversion trigger.

  • Single-channel, continuous-samples: Conversion of a single channel in a repeated fashion. Once a conversion is complete, the process immediately restarts.

  • Multi-channel (sequence), continuous-samples: A sequence of channels is converted continuously in order. Once a conversion is complete for all channels in the sequence, the process immediately restarts.

In addition to these modes, individual memories can also require triggering of samples. For example, consider a sequence of 8 channels to convert in Multi-channel, single-sample mode. Using an individual memory trigger, it is possible to cause 5 samples to be converted on one trigger, then the remaining 3 samples to be converted on a subsequent trigger. A similar effect would occur in continuous-sampling mode as well.

Configuration

The ADC12 modules can be configured with the structs and functions as described below. Note that the ADC itself requires an initialization and all used ADC memories need to be configured as well.

ADC Base

Configuration of the ADC’s conversion behavior requires the creation of an ADC_Config type struct. The table below shows the fields for this configuration struct.

ADC_Config struct fields

Field

type

Possible Values

.res

ADC_RESOLUTION (enum)

ADC_RESOLUTION_8BIT

ADC_RESOLUTION_10BIT

ADC_RESOLUTION_12BIT

.repeat

ADC_REPEAT (enum)

ADC_REPEAT_ENABLED

ADC_REPEAT_DISABLED

.sequence

ADC_SEQ (enum)

ADC_SEQ_SEQUENCE

ADC_SEQ_SINGLE

.trigsrc

uint8_t

0-15

.memStart

ADC_MEM_INDEX (enum)

ADC_MEM_INDEX_x where x may be 0 to 11

.memEnd

ADC_MEM_INDEX (enum)

ADC_MEM_INDEX_x where x may be 0 to 11

Field Descriptions:
  • .res sets the resolution of the ADC conversions. The ADC12 supports 8-bit (ADC_RESULTION_8BIT), 10-bit (ADC_RESULTION_10BIT), or 12-bit (ADC_RESULTION_12BIT) resolutions.

  • .repeat enables or disabled the “continuous-samples” mode as described above: if enabled, conversions are continuously performed given a single trigger. If disabled, only one conversion, or one sequence of conversions, is completed for each trigger. Not that additional triggers may be required in sequence mode; depending on ADC memory configuration.

  • .sequence configures the ADC for multi-channel operation (ADC_SEQ_SEQUENCE) or single-channel operation (ADC_SEQ_SINGLE).

  • .trigsrc specifies the trigger source for the ADC, where 0 indicates that the trigger must be provided through software. Values 1 through 15 will select configured published events.

Note

Support for “publishing events” is not currently possibe within the EmCon HAL; therefore, the .trigsrc field should always be set to 0.

  • .memStart specifies the ADC memory to convert for single-channel mode or the starting memory in a sequence for multi-channel mode.

  • .memEnd specifies the last ADC memory in a sequence for multi-channel mode. This field is ignored for single-channel mode.

With the configuration struct filled in, the timer can be initialized with the function:

void ADC_initADC( ADC_Regs *adc , ADC_Config *config )

ADC Channels/Memories

Each channel to be converted by the ADC must be associated with a single ADC “memory”. Each memory requires configuration and produces one output result; stored independently of other memories.

Configuration of an ADC memory requires the creation of an ADC_ChanConfig type struct. The table below shows the fields for this configuration struct.

ADC_ChanConfig struct fields

Field

type

Possible Values

.channel

uint32_t

0-15

.mem

ADC_MEM_INDEX (enum)

ADC_MEM_INDEX_x where x may be 0 to 11

.vref

ADC_VREF (enum)

ADC_VREF_VDD

ADC_VREF_EXT

ADC_VREF_INT

.trigMode

ADC_TRIGMODE (enum)

ADC_TRIGMODE_AUTO

ADC_TRIGMODE_TRIG

Field Descriptions:
  • .channel selects the ADC input channel to associate with a memory, specified with a value of 0 to 15. These input channels are exposed on GPIO Pins, with the mapping provided in ADC Channel Pin Map.

  • .mem selects the ADC memory to associate with the input channel above.

  • .vref selects the positive voltage reference to use for the conversion of the desired channel. There are three options for this field:

    • ADC_VREF_VDD: Selects the reference to be the microcontroller power supply, VDD, which is +3.3 V.

    • ADC_VREF_EXT: Selects an external voltage applied to the VREF+ pin.

    • ADC_VREF_INT: Selects the internally generated voltage for the reference voltage. The internal voltage must be enabled and be selected between either 1.4 V and 2.5 V, see Internal Reference Voltage Generator below on how to do so.

  • .trigMode using value ADC_TRIGMODE_TRIG sets the channel to require an independent trigger for each conversion, regardless of .repeat and .sequence fields in ADC_Config. Setting this field to ADC_TRIGMODE_AUTO will not require an independent trigger.

With this configuration struct filled in, the channel/memory can be configured with the function:

void ADC_initChannel( ADC_Regs *adc , ADC_ChanConfig *config )

The above function must be used for each channel to be enabled.

Internal Reference Voltage Generator

The reference voltage for the ADC12 module may be sources from an internal generator: VREF. The voltage generated by this module is shared between the ADC12 modules, the DAC module, the COMP modules, and the OPA modules.

The internal voltage reference can be configured with the function:

  • void VREF_setReference( VREF_Regs *vref , VREF_V output )

where VREF_Regs *vref is the VREF module, simply just VREF, and VREF_V output can take three values:

  • VREF_V_OFF: Disables the output voltage reference

  • VREF_V_1V4: Set the output voltage reference to 1.4 V

  • VREF_V_2V5: Set the output voltage reference to 2.5 V

Sampling Control

With the ADC configured, conversions can be controlled by the following functions:

  • void ADC_enableConversions( ADC_Regs *adc )/void ADC_disableConversions( ADC_Regs *adc ): enable or disable (block) conversions from occurring. Conversions must be disabled to perform ADC12 reconfiguration. Conversions need to be re-enabled for each sample in single-sample mode. They do not need to be re-enabled for repeated sampling (continuous-sampling mode).

  • void  ADC_startConversion( ADC_Regs *adc ): Software request for an ADC conversion. Note that for ease of use, this function is written to include a call to ADC_enableConversion() to avoid having to call both functions in single-sample mode.

  • uint32_t ADC_getStatus( ADC_Regs *adc ): Returns 1 if the ADC is currently performing a conversion in single-sample mode and 0 otherwise. In continuous-sampling mode this function will return 1 continuously if conversions have been triggered once; even if the ADC is currently waiting for a memory-specific trigger.

  • uint16_t ADC_getResult( ADC_Regs *adc , ADC_MEM_INDEX mem ): Fetch a completed ADC conversion from the ADC12 conversion memory ADC_MEM_INDEX mem. Valid values are ADC_MEM_INDEX_0 through ADC_MEM_INDEX_11.

Interrupts

An ADC12 has a possible 19 total events which may trigger an interrupt. The bulk of these events are indications that a conversion has completed for a specific ADC memory. A list of all possible sources is as follows:

  • ADC_INTSRC_MEMx, where x may be 0 through 11: Triggered when the corresponding ADC memory has been loaded with a newly completed conversion

  • ADC_INTSRC_OVERFLOW: Triggered when a previously converted but unread result has been overwritten by a newer conversion.

  • ADC_INTSRC_TRIG_OVF: Triggered during a multi-channel conversion when a new sampling trigger is received before the previous sampling sequence has completed.

  • ADC_INTSRC_WINDOW_COMP_HIGH: Triggered when the ADC detects a conversion result with a value above an upper bound.

  • ADC_INTSRC_WINDOW_COMP_LOW: Triggered when the ADC detects a conversion result with a value below a lower bound.

  • ADC_INTSRC_WINDOW_COMP_IN: Triggered when the ADC detects a conversion result with a value between a lower bound and an upper bound.

  • ADC_INTSRC_DMA_DONE: Triggered when the DMA has completed transferring a set block size of ADC results.

  • ADC_INTSRC_UNDERFLOW: Triggered when an ADC memory result register is read prior to a new conversion being available.

    Note

    The ADC_INTSRC_WINDOW_x and ADC_INTSRC_DMA_DONE events do not have the required module support implemented in the EmCon HAL in order to be useful.

All of the above interrupt sources will trigger a single interrupt request handler per ADC, or IRQ Handler; that is, each ADC has a one IRQ Handler each: ADC0_IRQHandler() and ADC1_IRQHandler().

Enabling Interrupts

Each interrupt source may be individually enabled and disabled through the functions:

  • void ADC_enableInterrupt( ADC_Regs *adc , uint32_t interruptMask )

  • void ADC_disableInterrupt( ADC_Regs *adc , uint32_t interruptMask )

where uint32_t interruptMask is the desired interrupt source(s) to enable/disable, listed above. If multiple sources are desired, they are combined via a bitwise OR or enabled independently. These functions must be called after :code:`void ADC_initADC()`, otherwise the requested change will be reverted.

Further, the associated ADC interrupt must also be enabled in the CPU with

NVIC_EnableIRQ( IRQn_Type IRQn )

where IRQn_Type IRQn is a defined identifier corresponding to either ADC0 or ADC1, either ADC0_INT_IRQn or ADC1_INT_IRQn.

Each ADC interrupt, if enabled, must have an associated IRQ Handler function. These functions must be named to pre-defined required names such that the interrupt requests are linked as desired. These are either

void ADC0_IRQHandler(void) or void ADC1_IRQHandler(void)

Interrupt Handling

The IRQ Handler associated with an interrupt will automatically be called when the specific interrupt is triggered. Within this function, the code must determine which interrupt source(s) triggered the handler. This may be done with one of three functions:

  • uint32_t ADC_getActiveInterrupt( ADC_Regs *adc ):

    • Indicates the highest priority interrupt source pending for the corresponding module and will acknowledge the interrupt source. The function will return one of ADC_INTSRC_x defined values as listed above. If using this identification method, the IRQ Handler will be called repeatedly until all enabled sources are acted upon.

  • uint32_t ADC_getPendingInterrupts( ADC_Regs *adc ):

    • Returns all interrupt sources that are currently pending and enabled for the corresponding module without achnowledging any interrupt source. This is a bitwise OR combination of the corresponding ADC_INTSRC_x defined values as listed above. If using this identification method, only one IRQ Handler call is needed for all sources to be acted upon.

  • uint32_t ADC_getAllPendingInterrupts( ADC_Regs *adc ):

    • Returns all interrupt sources that are currently pending, including disabled sources, for the corresponding module without achnowledging any interrupt source. This is a bitwise OR combination of the corresponding ADC_INTSRC_x defined values as listed above. If using this identification method, only one IRQ Handler call is needed for all sources to be acted upon.

If using the second or third functions as given above, each enabled interrupt source must be acknowledged (done automatically using the first function). If this acknowledgment is not done, the interrupt will continuously trigger; that is, the IRQ Handler will be immediately called again once it completes, erroneously. To acknowledge, or clear an interrupt source, use the following function:

  • void ADC_clearInterrupt( ADC_Regs *adc , uint32_t interruptMask )

where uint32_t interruptMask is the desired interrupt source(s) to acknowledge and clear. If multiple sources are desired to be acknowledged, they are combined via a bitwise OR or enabled independently.

ADC Channel Pin Map

Below is the connections for all ADC channels. Signals in italics are connections to other functionality internal to the microcontroller. Signals in bold are those available on the RSLK. Additional connections to other analog subsystems exist but are not documented here.

ADC Channel Mapping

Channel

ADC0

ADC1

0

PA27

PA15

1

PA26

PA16

2

PA25

PA17

3

PA24

PA18

4

PB25

PB17

5

PB24

PB18

6

PB20

PB19

7

PA22

PA21

8

PA21

PA22

9

10

11

Temp Sensor

12

PA14

Temp Sensor

13

OPA0 Output

OPA1 Output

14

GPAMP Output

GPAMP Output

15

Supply Monitor

Supply Monitor