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:
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:
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.
Field |
type |
Possible Values |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- Field Descriptions:
.ressets 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..repeatenables 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..sequenceconfigures the ADC for multi-channel operation (ADC_SEQ_SEQUENCE) or single-channel operation (ADC_SEQ_SINGLE)..trigsrcspecifies the trigger source for the ADC, where0indicates that the trigger must be provided through software. Values1through15will select configured published events.
Note
Support for “publishing events” is not currently possibe within the EmCon HAL; therefore, the
.trigsrcfield should always be set to0..memStartspecifies the ADC memory to convert for single-channel mode or the starting memory in a sequence for multi-channel mode..memEndspecifies 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.
Field |
type |
Possible Values |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
- Field Descriptions:
.channelselects the ADC input channel to associate with a memory, specified with a value of0to15. These input channels are exposed on GPIO Pins, with the mapping provided in ADC Channel Pin Map..memselects the ADC memory to associate with the input channel above..vrefselects 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.
.trigModeusing valueADC_TRIGMODE_TRIGsets the channel to require an independent trigger for each conversion, regardless of.repeatand.sequencefields inADC_Config. Setting this field toADC_TRIGMODE_AUTOwill 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 ): Returns1if the ADC is currently performing a conversion in single-sample mode and0otherwise. In continuous-sampling mode this function will return1continuously 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 memoryADC_MEM_INDEX mem. Valid values areADC_MEM_INDEX_0throughADC_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, wherexmay be0through11: 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_xandADC_INTSRC_DMA_DONEevents 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)orvoid 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_xdefined 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_xdefined 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_xdefined 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.
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 |