This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSPM0G1507: ADC

Part Number: MSPM0G1507
Other Parts Discussed in Thread: LP-MSPM0G3507

Tool/software:

Dear TI Engineers,

I hope this message finds you well. I am currently working on an ADC configuration based on the example "adc_singlechannel" (PA22 → ADC0, PA17 → ADC1 TI_driver). Initially, I had a 2-channel setup (ADC0 and ADC1), but I expanded ADC0 from 1 channel to 6 channels. However, I am encountering an issue where connecting 3.3V to PA22 affects all readings except for ADC0_3.

Here is the observed behavior:

When 3.3V is connected to PA22, all ADC readings are affected except for ADC0_3.

When 3.3V is connected to PA17, ADC0_3 shows a reading.

When 3.3V is connected to PA15, no effect is observed.

The pin-to-channel mapping is as follows:

A0_7→ PA22

A0_12 → PA14

A0_0 → PA27

A0_1 → PA26

A0_2 → PA25

A0_3 → PA24

A1_0 → PA15

Could you please provide guidance on why connecting 3.3V to PA22 affects all channels except ADC0_3? Additionally, why does connecting 3.3V to PA17 result in a reading for ADC0_3, while connecting to PA15 has no effect?

Thank you for your time and support. I look forward to your insights.

Best regards,

Pakho

void *adcSrvThread(void *arg) {
    AdcSrv_Handle adcSrv;           // ADC service handle
    // Statistics for 6 ADC0 channels and 1 ADC1 channel
    AdcSampleStats stats0;    // ADC0 Channel 7 (A0_7 - AMP_ID)
    AdcSampleStats stats0_12; // ADC0 Channel 12 (A0_12 - HW_ID)
    AdcSampleStats stats0_0;  // ADC0 Channel 0 (A0_0 - CH1_FET1_NTC)
    AdcSampleStats stats0_1;  // ADC0 Channel 1 (A0_1 - CH1_FET2_NTC)
    AdcSampleStats stats0_2;  // ADC0 Channel 2 (A0_2 - CH2_FET1_NTC)
    AdcSampleStats stats0_3;  // ADC0 Channel 3 (A0_3 - CH2_FET2_NTC)
    AdcSampleStats stats1;    // ADC1 Channel
    
    // Initialize ADC service
    if (AdcSrv_init(&adcSrv) != 0) {
        LOG_PRINT_ERR("ADC service initialization failed");
        return NULL;
    }
    
    LOG_PRINT_INF("ADC service started with 6 channels");
    
    uint32_t cycle_count = 0;
    while (1) {
        // Clear statistics for all channels
        memset(&stats0, 0, sizeof(AdcSampleStats));
        memset(&stats0_12, 0, sizeof(AdcSampleStats));
        memset(&stats0_0, 0, sizeof(AdcSampleStats));
        memset(&stats0_1, 0, sizeof(AdcSampleStats));
        memset(&stats0_2, 0, sizeof(AdcSampleStats));
        memset(&stats0_3, 0, sizeof(AdcSampleStats));
        memset(&stats1, 0, sizeof(AdcSampleStats));
        
        // Perform ADC sampling cycle with correct parameter order
        // Order: stats0 (A0_7), stats0_12 (A0_12), stats0_0 (A0_0), stats0_1 (A0_1), stats0_2 (A0_2), stats0_3 (A0_3), stats1 (ADC1)
        if (AdcSrv_sampleCycle(&adcSrv, &stats0, &stats0_12, &stats0_0, &stats0_1, &stats0_2, &stats0_3, &stats1) != 0) {
            break;
        }
        
        // Display results for all 6 ADC0 channels
        if (stats0.avg > 0) {
            LOG_PRINT_DBG("ADC0_7(AMP_ID)[%lu]: min=%d, max=%d, avg=%d (%.2f V)", 
                          cycle_count, stats0.min, stats0.max, stats0.avg,
                          (float)stats0.microvolts / 1000000.0f);
        }
        
        if (stats0_12.avg > 0) {
            LOG_PRINT_DBG("ADC0_12(HW_ID)[%lu]: min=%d, max=%d, avg=%d (%.2f V)", 
                          cycle_count, stats0_12.min, stats0_12.max, stats0_12.avg,
                          (float)stats0_12.microvolts / 1000000.0f);
        }
        
        if (stats0_0.avg > 0) {
            LOG_PRINT_DBG("ADC0_0(CH1_FET1_NTC)[%lu]: min=%d, max=%d, avg=%d (%.2f V)", 
                          cycle_count, stats0_0.min, stats0_0.max, stats0_0.avg,
                          (float)stats0_0.microvolts / 1000000.0f);
        }
        
        if (stats0_1.avg > 0) {
            LOG_PRINT_DBG("ADC0_1(CH1_FET2_NTC)[%lu]: min=%d, max=%d, avg=%d (%.2f V)", 
                          cycle_count, stats0_1.min, stats0_1.max, stats0_1.avg,
                          (float)stats0_1.microvolts / 1000000.0f);
        }
        
        if (stats0_2.avg > 0) {
            LOG_PRINT_DBG("ADC0_2(CH2_FET1_NTC)[%lu]: min=%d, max=%d, avg=%d (%.2f V)", 
                          cycle_count, stats0_2.min, stats0_2.max, stats0_2.avg,
                          (float)stats0_2.microvolts / 1000000.0f);
        }
        
        if (stats0_3.avg > 0) {
            LOG_PRINT_DBG("ADC0_3(CH2_FET2_NTC)[%lu]: min=%d, max=%d, avg=%d (%.2f V)", 
                          cycle_count, stats0_3.min, stats0_3.max, stats0_3.avg,
                          (float)stats0_3.microvolts / 1000000.0f);
        }
        
        // Display results for ADC1 channel
        if (stats1.avg > 0) {
            LOG_PRINT_DBG("ADC1[%lu]: min=%d, max=%d, avg=%d (%.2f V)", 
                          cycle_count, stats1.min, stats1.max, stats1.avg,
                          (float)stats1.microvolts / 1000000.0f);
        }

        LOG_PRINT_DBG("----------------------");
        cycle_count++;
        usleep(CYCLE_DELAY_MS * 1000);
    }
    
    // Cleanup ADC service
    AdcSrv_close(&adcSrv);
    return NULL;
}

/**
 * @file AdcDrv.c
 * @brief ADC Driver Implementation
 * 
 * This file implements the low-level ADC driver functionality for dual-channel
 * ADC operations. It provides initialization, reading, and cleanup operations
 * for two ADC channels.
 */

#include "AdcDrv.h"
#include <ti/drivers/ADC.h>
#include "ti_drivers_config.h"

/**
 * @brief Initialize ADC Driver
 * 
 * Initializes all ADC channels with default parameters.
 * 
 * @param handle Pointer to ADC driver handle structure
 * @return 0 on success, negative error code on failure
 */
int AdcDrv_init(AdcDrv_Handle *handle) {
    ADC_Params params;
    ADC_Params_init(&params);
    
    // Initialize ADC0 channels
    handle->adc0 = ADC_open(CONFIG_ADC_0, &params); // A0_7 (AMP_ID)
    if (handle->adc0 == NULL) {
        return -1; // ADC0 initialization failed
    }
    
    // Initialize additional ADC0 channels
    handle->adc0_12 = ADC_open(CONFIG_ADC_2, &params); // A0_12 (HW_ID)
    if (handle->adc0_12 == NULL) {
        AdcDrv_close(handle);
        return -2; // ADC0_12 initialization failed
    }
    
    handle->adc0_0 = ADC_open(CONFIG_ADC_3, &params); // A0_0 (CH1_FET1_NTC)
    if (handle->adc0_0 == NULL) {
        AdcDrv_close(handle);
        return -3; // ADC0_0 initialization failed
    }
    
    handle->adc0_1 = ADC_open(CONFIG_ADC_4, &params); // A0_1 (CH1_FET2_NTC)
    if (handle->adc0_1 == NULL) {
        AdcDrv_close(handle);
        return -4; // ADC0_1 initialization failed
    }
    
    handle->adc0_2 = ADC_open(CONFIG_ADC_5, &params); // A0_2 (CH2_FET1_NTC)
    if (handle->adc0_2 == NULL) {
        AdcDrv_close(handle);
        return -5; // ADC0_2 initialization failed
    }
    
    handle->adc0_3 = ADC_open(CONFIG_ADC_6, &params); // A0_3 (CH2_FET2_NTC)
    if (handle->adc0_3 == NULL) {
        AdcDrv_close(handle);
        return -6; // ADC0_3 initialization failed
    }
    
    // Initialize ADC1 channel
    handle->adc1 = ADC_open(CONFIG_ADC_1, &params);
    if (handle->adc1 == NULL) {
        AdcDrv_close(handle);
        return -7; // ADC1 initialization failed
    }
    
    return 0; // Success
}

/**
 * @brief Read from ADC Channel 0
 * 
 * Performs a single conversion on ADC channel 0 and returns the result.
 * Checks if the ADC handle is valid before conversion.
 * 
 * @param handle Pointer to ADC driver handle structure
 * @param value Pointer to store the ADC conversion result
 * @return 0 on success, -1 if ADC handle is invalid
 */
int AdcDrv_readChannel0(AdcDrv_Handle *handle, uint16_t *value) {
    if (handle->adc0 == NULL) return -1;
    return ADC_convert(handle->adc0, value);
}

/**
 * @brief Read ADC Channel 1
 * 
 * Reads the value from ADC channel 1. If the conversion fails, it returns -1.
 * 
 * @param handle Pointer to ADC driver handle structure
 * @param value Pointer to store the read ADC value
 * @return 0 on success, -1 on failure
 */
int AdcDrv_readChannel1(AdcDrv_Handle *handle, uint16_t *value) {
    if (handle->adc1 == NULL) return -1;
    return ADC_convert(handle->adc1, value);
}

/**
 * @brief Read ADC0 Channel 12 (HW_ID)
 * 
 * Reads the value from ADC0 channel 12. If the conversion fails, it returns -1.
 * 
 * @param handle Pointer to ADC driver handle structure
 * @param value Pointer to store the read ADC value
 * @return 0 on success, -1 on failure
 */
int AdcDrv_readChannel0_12(AdcDrv_Handle *handle, uint16_t *value) {
    if (handle->adc0_12 == NULL) return -1;
    return ADC_convert(handle->adc0_12, value);
}

/**
 * @brief Read ADC0 Channel 0 (CH1_FET1_NTC)
 * 
 * Reads the value from ADC0 channel 0. If the conversion fails, it returns -1.
 * 
 * @param handle Pointer to ADC driver handle structure
 * @param value Pointer to store the read ADC value
 * @return 0 on success, -1 on failure
 */
int AdcDrv_readChannel0_0(AdcDrv_Handle *handle, uint16_t *value) {
    if (handle->adc0_0 == NULL) return -1;
    return ADC_convert(handle->adc0_0, value);
}

/**
 * @brief Read ADC0 Channel 1 (CH1_FET2_NTC)
 * 
 * Reads the value from ADC0 channel 1. If the conversion fails, it returns -1.
 * 
 * @param handle Pointer to ADC driver handle structure
 * @param value Pointer to store the read ADC value
 * @return 0 on success, -1 on failure
 */
int AdcDrv_readChannel0_1(AdcDrv_Handle *handle, uint16_t *value) {
    if (handle->adc0_1 == NULL) return -1;
    return ADC_convert(handle->adc0_1, value);
}

/**
 * @brief Read ADC0 Channel 2 (CH2_FET1_NTC)
 * 
 * Reads the value from ADC0 channel 2. If the conversion fails, it returns -1.
 * 
 * @param handle Pointer to ADC driver handle structure
 * @param value Pointer to store the read ADC value
 * @return 0 on success, -1 on failure
 */
int AdcDrv_readChannel0_2(AdcDrv_Handle *handle, uint16_t *value) {
    if (handle->adc0_2 == NULL) return -1;
    return ADC_convert(handle->adc0_2, value);
}

/**
 * @brief Read ADC0 Channel 3 (CH2_FET2_NTC)
 * 
 * Reads the value from ADC0 channel 3. If the conversion fails, it returns -1.
 * 
 * @param handle Pointer to ADC driver handle structure
 * @param value Pointer to store the read ADC value
 * @return 0 on success, -1 on failure
 */
int AdcDrv_readChannel0_3(AdcDrv_Handle *handle, uint16_t *value) {
    if (handle->adc0_3 == NULL) return -1;
    return ADC_convert(handle->adc0_3, value);
}

/**
 * @brief Close ADC Driver
 * 
 * Closes all ADC channels and cleans up their resources. Sets the handles
 * to NULL after closing to prevent accidental reuse.
 * 
 * @param handle Pointer to ADC driver handle structure
 */
void AdcDrv_close(AdcDrv_Handle *handle) {
    // Close all ADC0 channels if they exist
    if (handle->adc0) {
        ADC_close(handle->adc0);
        handle->adc0 = NULL;
    }
    
    if (handle->adc0_12) {
        ADC_close(handle->adc0_12);
        handle->adc0_12 = NULL;
    }
    
    if (handle->adc0_0) {
        ADC_close(handle->adc0_0);
        handle->adc0_0 = NULL;
    }
    
    if (handle->adc0_1) {
        ADC_close(handle->adc0_1);
        handle->adc0_1 = NULL;
    }
    
    if (handle->adc0_2) {
        ADC_close(handle->adc0_2);
        handle->adc0_2 = NULL;
    }
    
    if (handle->adc0_3) {
        ADC_close(handle->adc0_3);
        handle->adc0_3 = NULL;
    }
    
    // Close ADC1 channel if it exists
    if (handle->adc1) {
        ADC_close(handle->adc1);
        handle->adc1 = NULL;
    }
}
AdcDrv.h
/**
 * @file AdcSrv.c
 * @brief ADC Service Implementation
 * 
 * This file implements the ADC service layer that provides high-level ADC
 * functionality including multi-channel sampling and statistical analysis.
 * It uses the low-level ADC driver for actual ADC operations.
 */

#include "AdcSrv.h"
#include "AdcDrv.h"
#include <unistd.h>

/**
 * @brief Sampling delay in microseconds
 * 
 * Defines the delay between consecutive ADC samples to allow proper
 * signal settling and prevent ADC overload.
 */
#define SAMPLE_DELAY_US 10000

/**
 * @brief Number of samples per channel per cycle
 * 
 * Defines how many samples to take from each ADC channel in one
 * sampling cycle for statistical analysis.
 */
#define SAMPLE_COUNT 5

/**
 * @brief Static ADC driver instance
 * 
 * This structure maintains the state of the underlying ADC driver
 * and is used by all ADC service operations.
 */
static AdcDrv_Handle adcDrv;

/**
 * @brief Initialize ADC Service
 * 
 * Initializes the ADC service by setting up the service handle and
 * initializing the underlying ADC driver. The service is marked as
 * running and configured with the default sample count.
 * 
 * @param handle Pointer to ADC service handle structure
 * @return 0 on success, negative error code on failure
 */
int AdcSrv_init(AdcSrv_Handle *handle) {
    // Set initial service state
    handle->running = true;
    handle->sample_count = SAMPLE_COUNT;
    
    // Initialize underlying ADC driver
    int ret = AdcDrv_init(&adcDrv);
    if (ret != 0) {
        return ret; // Propagate error code
    }
    
    return 0; // Success
}

/**
 * @brief Execute Single Sampling Cycle
 * 
 * Performs a complete sampling cycle on all ADC channels, collecting
 * multiple samples from each channel and calculating statistical data
 * (min, max, average) for each channel.
 * 
 * @param handle Pointer to ADC service handle structure
 * @param stats0 Pointer to statistics structure for ADC0 channel 7 (AMP_ID)
 * @param stats0_12 Pointer to statistics structure for ADC0 channel 12 (HW_ID)
 * @param stats0_0 Pointer to statistics structure for ADC0 channel 0 (CH1_FET1_NTC)
 * @param stats0_1 Pointer to statistics structure for ADC0 channel 1 (CH1_FET2_NTC)
 * @param stats0_2 Pointer to statistics structure for ADC0 channel 2 (CH2_FET1_NTC)
 * @param stats0_3 Pointer to statistics structure for ADC0 channel 3 (CH2_FET2_NTC)
 * @param stats1 Pointer to statistics structure for ADC1 channel
 * @return 0 on success, -1 if service is not running, -2 if invalid parameters
 */
int AdcSrv_sampleCycle(AdcSrv_Handle *handle, 
                      AdcSampleStats *stats0, 
                      AdcSampleStats *stats0_12, 
                      AdcSampleStats *stats0_0, 
                      AdcSampleStats *stats0_1, 
                      AdcSampleStats *stats0_2, 
                      AdcSampleStats *stats0_3, 
                      AdcSampleStats *stats1) {
    // Check if service is running
    if (!handle->running) return -1;
    
    // Validate input parameters
    if (handle == NULL || stats0 == NULL || stats0_12 == NULL || stats0_0 == NULL || 
        stats0_1 == NULL || stats0_2 == NULL || stats0_3 == NULL || stats1 == NULL) {
        return -2; // Invalid input parameters
    }
    
    // Initialize statistics variables
    uint16_t min0 = 0xFFFF, max0 = 0, sum0 = 0;
    uint16_t min0_12 = 0xFFFF, max0_12 = 0, sum0_12 = 0;
    uint16_t min0_0 = 0xFFFF, max0_0 = 0, sum0_0 = 0;
    uint16_t min0_1 = 0xFFFF, max0_1 = 0, sum0_1 = 0;
    uint16_t min0_2 = 0xFFFF, max0_2 = 0, sum0_2 = 0;
    uint16_t min0_3 = 0xFFFF, max0_3 = 0, sum0_3 = 0;
    uint16_t min1 = 0xFFFF, max1 = 0, sum1 = 0;
    int samples0 = 0, samples0_12 = 0, samples0_0 = 0, samples0_1 = 0, samples0_2 = 0, samples0_3 = 0, samples1 = 0;
    
    // Collect samples from all channels
    for (int i = 0; i < handle->sample_count; i++) {
        uint16_t val;
        int res;
        
        // Sample from channel 0 (A0_7 - AMP_ID)
        res = AdcDrv_readChannel0(&adcDrv, &val);
        if (res == 0) {
            // Update channel 0 statistics
            if (val < min0) min0 = val;
            if (val > max0) max0 = val;
            sum0 += val;
            samples0++;
        }
        
        // Sample from channel 0_12 (A0_12 - HW_ID)
        res = AdcDrv_readChannel0_12(&adcDrv, &val);
        if (res == 0) {
            // Update channel 0_12 statistics
            if (val < min0_12) min0_12 = val;
            if (val > max0_12) max0_12 = val;
            sum0_12 += val;
            samples0_12++;
        }
        
        // Sample from channel 0_0 (A0_0 - CH1_FET1_NTC)
        res = AdcDrv_readChannel0_0(&adcDrv, &val);
        if (res == 0) {
            // Update channel 0_0 statistics
            if (val < min0_0) min0_0 = val;
            if (val > max0_0) max0_0 = val;
            sum0_0 += val;
            samples0_0++;
        }
        
        // Sample from channel 0_1 (A0_1 - CH1_FET2_NTC)
        res = AdcDrv_readChannel0_1(&adcDrv, &val);
        if (res == 0) {
            // Update channel 0_1 statistics
            if (val < min0_1) min0_1 = val;
            if (val > max0_1) max0_1 = val;
            sum0_1 += val;
            samples0_1++;
        }
        
        // Sample from channel 0_2 (A0_2 - CH2_FET1_NTC)
        res = AdcDrv_readChannel0_2(&adcDrv, &val);
        if (res == 0) {
            // Update channel 0_2 statistics
            if (val < min0_2) min0_2 = val;
            if (val > max0_2) max0_2 = val;
            sum0_2 += val;
            samples0_2++;
        }
        
        // Sample from channel 0_3 (A0_3 - CH2_FET2_NTC)
        res = AdcDrv_readChannel0_3(&adcDrv, &val);
        if (res == 0) {
            // Update channel 0_3 statistics
            if (val < min0_3) min0_3 = val;
            if (val > max0_3) max0_3 = val;
            sum0_3 += val;
            samples0_3++;
        }
        
        // Sample from channel 1
        res = AdcDrv_readChannel1(&adcDrv, &val);
        if (res == 0) {
            // Update channel 1 statistics
            if (val < min1) min1 = val;
            if (val > max1) max1 = val;
            sum1 += val;
            samples1++;
        }
        
        // Delay between samples
        usleep(SAMPLE_DELAY_US);
    }
    
    // Calculate and store channel 0 statistics
    if (samples0 > 0) {
        stats0->min = min0;
        stats0->max = max0;
        stats0->avg = sum0 / samples0;
        stats0->microvolts = ADC_convertRawToMicroVolts(adcDrv.adc0, stats0->avg);
    }
    
    // Calculate and store channel 0_12 statistics
    if (samples0_12 > 0) {
        stats0_12->min = min0_12;
        stats0_12->max = max0_12;
        stats0_12->avg = sum0_12 / samples0_12;
        stats0_12->microvolts = ADC_convertRawToMicroVolts(adcDrv.adc0_12, stats0_12->avg);
    }
    
    // Calculate and store channel 0_0 statistics
    if (samples0_0 > 0) {
        stats0_0->min = min0_0;
        stats0_0->max = max0_0;
        stats0_0->avg = sum0_0 / samples0_0;
        stats0_0->microvolts = ADC_convertRawToMicroVolts(adcDrv.adc0_0, stats0_0->avg);
    }
    
    // Calculate and store channel 0_1 statistics
    if (samples0_1 > 0) {
        stats0_1->min = min0_1;
        stats0_1->max = max0_1;
        stats0_1->avg = sum0_1 / samples0_1;
        stats0_1->microvolts = ADC_convertRawToMicroVolts(adcDrv.adc0_1, stats0_1->avg);
    }
    
    // Calculate and store channel 0_2 statistics
    if (samples0_2 > 0) {
        stats0_2->min = min0_2;
        stats0_2->max = max0_2;
        stats0_2->avg = sum0_2 / samples0_2;
        stats0_2->microvolts = ADC_convertRawToMicroVolts(adcDrv.adc0_2, stats0_2->avg);
    }
    
    // Calculate and store channel 0_3 statistics
    if (samples0_3 > 0) {
        stats0_3->min = min0_3;
        stats0_3->max = max0_3;
        stats0_3->avg = sum0_3 / samples0_3;
        stats0_3->microvolts = ADC_convertRawToMicroVolts(adcDrv.adc0_3, stats0_3->avg);
    }
    
    // Calculate and store channel 1 statistics
    if (samples1 > 0) {
        stats1->min = min1;
        stats1->max = max1;
        stats1->avg = sum1 / samples1;
        stats1->microvolts = ADC_convertRawToMicroVolts(adcDrv.adc1, stats1->avg);
    }
    
    return 0;
}

/**
 * @brief Close ADC Service
 * 
 * Stops the ADC service and cleans up resources by marking the service
 * as not running and closing the underlying ADC driver.
 * 
 * @param handle Pointer to ADC service handle structure
 */
void AdcSrv_close(AdcSrv_Handle *handle) {
    // Mark service as stopped
    handle->running = false;
    
    // Clean up underlying driver resources
    AdcDrv_close(&adcDrv);
}
AdcSrv.h
/*
 * Copyright (c) 2023, Texas Instruments Incorporated
 * All rights reserved.
 *
 * 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.
 */

/*
 *  ======== ti_drivers_config.c ========
 *  Configured TI-Drivers module definitions
 */

#include <stddef.h>
#include <stdint.h>

#include <ti/devices/DeviceFamily.h>
#include "ti_drivers_config.h"

/*
 *  ============================= Display =============================
 */

#include <ti/display/Display.h>
#include <ti/display/DisplayUart.h>

#define CONFIG_Display_COUNT 1

const uint_least8_t CONFIG_UART_0 = 0;
const uint_least8_t CONFIG_UART_1 = 1;
const uint_least8_t UART_count    = CONFIG_UART_COUNT;

#define DISPLAY_UARTBUFFERSIZE 100
static char displayUARTBuffer[DISPLAY_UARTBUFFERSIZE];

DisplayUart_Object displayUartObject;

const DisplayUart_HWAttrs displayUartHWAttrs = {.uartIdx = CONFIG_UART_1,
    .baudRate                                            = 115200,
    .mutexTimeout                                        = (unsigned int) (-1),
    .strBuf                                              = displayUARTBuffer,
    .strBufLen = DISPLAY_UARTBUFFERSIZE};

const Display_Config Display_config[CONFIG_Display_COUNT] = {
    /* CONFIG_Display_0 */
    /* XDS110 UART */
    {.fxnTablePtr = &DisplayUartMin_fxnTable,
        .object   = &displayUartObject,
        .hwAttrs  = &displayUartHWAttrs},
};

const uint_least8_t Display_count = CONFIG_Display_COUNT;
/*
 *  =============================== DMA ===============================
 */
#include <ti/drivers/dma/DMAMSPM0.h>
const uint_least8_t CONFIG_DMA_0               = 0;
const uint_least8_t DMA_Count                  = CONFIG_DMA_COUNT;
DMAMSPM0_Object DMAObject[CONFIG_DMA_CH_COUNT] = {
    {.dmaTransfer =
            {
                .rxTrigger              = DMA_UART0_RX_TRIG,
                .rxTriggerType          = DL_DMA_TRIGGER_TYPE_EXTERNAL,
                .transferMode           = DL_DMA_SINGLE_TRANSFER_MODE,
                .extendedMode           = DL_DMA_NORMAL_MODE,
                .destWidth              = DL_DMA_WIDTH_BYTE,
                .srcWidth               = DL_DMA_WIDTH_BYTE,
                .destIncrement          = DL_DMA_ADDR_INCREMENT,
                .dmaChannel             = 0,
                .dmaTransferSource      = NULL,
                .dmaTransferDestination = NULL,
                .enableDMAISR           = false,
            }},
};

static const DMAMSPM0_HWAttrs DMAMSP0HWAttrs[CONFIG_DMA_COUNT] = {
    {
        .dmaIsrFxn          = NULL,
        .intPriority        = DEFAULT_DMA_PRIORITY,
        .roundRobinPriority = 0,
    },
};
const DMAMSPM0_Cfg DMAMSPM0_Config[CONFIG_DMA_COUNT] = {
    {
        &DMAMSP0HWAttrs[CONFIG_DMA_0],
        &DMAObject[CONFIG_DMA_0],
    },
};

/*
 *  =============================== GPIO ===============================
 */
#include <ti/drivers/GPIO.h>
#include <ti/drivers/gpio/GPIOMSPM0.h>

/* The range of pins available on this device */
const uint_least8_t GPIO_pinLowerBound = 0;
const uint_least8_t GPIO_pinUpperBound = 60;

/*
 *  ======== gpioPinConfigs ========
 *  Array of Pin configurations
 */
GPIO_PinConfig gpioPinConfigs[60] = {
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PA0 - I2C SDA */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PA1 - I2C SCL */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PA2 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PA3 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PA4 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PA5 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PA6 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PA7 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PA8 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PA9 */
    GPIO_CFG_OUTPUT | GPIO_CFG_OUT_HIGH, /* PA10:CONFIG_GPIO_UART2_0_TX */
    GPIO_CFG_INPUT | GPIO_CFG_IN_INT_NONE |
        GPIO_CFG_IN_PD,                  /* PA11:CONFIG_GPIO_UART2_0_RX */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PA12 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PA13 */
    /* Owned by CONFIG_ADC_0, channel 12 as ADC Pin */
    GPIO_CFG_INPUT | GPIO_CFG_IN_INT_NONE |
        GPIO_CFG_IN_NOPULL,              /* PA14:CONFIG_GPIO_ADC_0_AIN12 (HW_ID) */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PA15 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PA16 */
    /* Owned by CONFIG_ADC_1, channel 2 as ADC Pin */
    GPIO_CFG_INPUT | GPIO_CFG_IN_INT_NONE |
        GPIO_CFG_IN_NOPULL,              /* PA17:CONFIG_GPIO_ADC_1_AIN */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PA18 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PA19 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PA20 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PA21 */
    /* Owned by CONFIG_ADC_0, channel 7 as ADC Pin */
    GPIO_CFG_INPUT | GPIO_CFG_IN_INT_NONE |
        GPIO_CFG_IN_NOPULL,              /* PA22:CONFIG_GPIO_ADC_0_AIN7 (AMP_ID) */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PA23 */
    /* Owned by CONFIG_ADC_0, channel 3 as ADC Pin */
    GPIO_CFG_INPUT | GPIO_CFG_IN_INT_NONE |
        GPIO_CFG_IN_NOPULL,              /* PA24:CONFIG_GPIO_ADC_0_AIN3 (CH2_FET2_NTC) */
    /* Owned by CONFIG_ADC_0, channel 2 as ADC Pin */
    GPIO_CFG_INPUT | GPIO_CFG_IN_INT_NONE |
        GPIO_CFG_IN_NOPULL,              /* PA25:CONFIG_GPIO_ADC_0_AIN2 (CH2_FET1_NTC) */
    /* Owned by CONFIG_ADC_0, channel 1 as ADC Pin */
    GPIO_CFG_INPUT | GPIO_CFG_IN_INT_NONE |
        GPIO_CFG_IN_NOPULL,              /* PA26:CONFIG_GPIO_ADC_0_AIN1 (CH1_FET2_NTC) */
    /* Owned by CONFIG_ADC_0, channel 0 as ADC Pin */
    GPIO_CFG_INPUT | GPIO_CFG_IN_INT_NONE |
        GPIO_CFG_IN_NOPULL,              /* PA27:CONFIG_GPIO_ADC_0_AIN0 (CH1_FET1_NTC) */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PA28 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PA29 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PA30 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PA31 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PB0 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PB1 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PB2 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PB3 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PB4 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PB5 */
    GPIO_CFG_OUT_STD | GPIO_CFG_OUT_HIGH | IOMUX_PINCM23,/* PB6 - AMP_RST */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PB7 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PB8 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PB9 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PB10 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PB11 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PB12 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PB13 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PB14 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PB15 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PB16 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PB17 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PB18 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PB19 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PB20 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PB21 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PB22 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PB23 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PB24 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PB25 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PB26 */
    GPIO_CFG_INPUT | GPIO_DO_NOT_CONFIG, /* PB27 */
};

/*
 *  ======== gpioCallbackFunctions ========
 *  Array of callback function pointers
 *  Change at runtime with GPIO_setCallback()
 */
GPIO_CallbackFxn gpioCallbackFunctions[60];

/*
 *  ======== gpioUserArgs ========
 *  Array of user argument pointers
 *  Change at runtime with GPIO_setUserArg()
 *  Get values with GPIO_getUserArg()
 */
void *gpioUserArgs[60];

const uint_least8_t CONFIG_GPIO_LED_0_CONST     = CONFIG_GPIO_LED_0;
const uint_least8_t CONFIG_GPIO_ADC_0_AIN_CONST = CONFIG_GPIO_ADC_0_AIN;
const uint_least8_t CONFIG_GPIO_ADC_1_AIN_CONST = CONFIG_GPIO_ADC_1_AIN;
const uint_least8_t CONFIG_GPIO_UART_0_TX_CONST = CONFIG_GPIO_UART_0_TX;
const uint_least8_t CONFIG_GPIO_UART_0_RX_CONST = CONFIG_GPIO_UART_0_RX;
const uint_least8_t CONFIG_I2C_CONTROLLER_CONST = CONFIG_I2C_0;

/*
 *  ======== GPIO_config ========
 */
const GPIO_Config GPIO_config = {.configs = (GPIO_PinConfig *) gpioPinConfigs,
    .callbacks   = (GPIO_CallbackFxn *) gpioCallbackFunctions,
    .userArgs    = gpioUserArgs,
    .intPriority = (~0)};

/*
 *  =============================== I2C Controller ===============================
 */

#include <ti/drivers/I2C.h>
#include <ti/drivers/i2c/I2CMSPM0.h>

#define CONFIG_I2C_COUNT 1

/*
 *  ======== i2cObjects ========
 */
I2CMSPM0_Object I2CMSPM0Objects[CONFIG_I2C_COUNT];

/*
 *  ======== i2cHWAttrs ========
 */
const I2CMSPM0_HWAttrs I2CMSPM0HWAttrs[CONFIG_I2C_COUNT] = {
    /* CONFIG_I2C_CONTROLLER */
    /* LaunchPad I2C */
    {
        .i2c         = I2C_INST,
        .intNum      = I2C_INST_INT_IRQN,
        .intPriority = (~0),

        .sdaPincm    = GPIO_I2C_IOMUX_SDA,
        .sdaPinIndex = GPIO_I2C_SDA_PIN,
        .sdaPinMux   = GPIO_I2C_IOMUX_SDA_FUNC,

        .sclPincm    = GPIO_I2C_IOMUX_SCL,
        .sclPinIndex = GPIO_I2C_SCL_PIN,
        .sclPinMux   = GPIO_I2C_IOMUX_SCL_FUNC,

        .clockSource              = DL_I2C_CLOCK_BUSCLK,
        .clockDivider             = DL_I2C_CLOCK_DIVIDE_1,
        .txIntFifoThr             = DL_I2C_TX_FIFO_LEVEL_BYTES_1,
        .rxIntFifoThr             = DL_I2C_RX_FIFO_LEVEL_BYTES_1,
        .isClockStretchingEnabled = true,
        .i2cClk                   = I2C_CLOCK_MHZ,
    },
};

/*
 *  ======== I2C_config ========
 */
const I2C_Config I2C_config[CONFIG_I2C_COUNT] = {
    /* CONFIG_I2C_CONTROLLER */
    /* LaunchPad I2C */
    {.object     = &I2CMSPM0Objects[CONFIG_I2C_0],
        .hwAttrs = &I2CMSPM0HWAttrs[CONFIG_I2C_0]},
};

const uint_least8_t CONFIG_I2C_CONST = CONFIG_I2C_0;
const uint_least8_t I2C_count        = CONFIG_I2C_COUNT;

/*
 *  =============================== ADC ===============================
 */

#include <ti/drivers/ADC.h>
#include <ti/drivers/adc/ADCMSPM0.h>

#define CONFIG_ADC_COUNT 8  // 1个ADC0实例 + 1个ADC1实例 + 6个ADC0通道

/*
 *  ======== adcMSPM0Objects ========
 */
ADCMSPM0_Object adcObjects[CONFIG_ADC_COUNT];

/*
 *  ======== adcMSPM0HWAttrs ========
 */
const ADCMSPM0_HWAttrs adcHWAttrs[CONFIG_ADC_COUNT] = {
    /* CONFIG_ADC_0 - Main ADC0 instance (A0_7 - AMP_ID) */
    {.adc                     = ADC_0_INST,
        .adcInputDIO          = CONFIG_GPIO_ADC_0_AIN7,
        .adcInputPincm        = CONFIG_GPIO_ADC_0_AIN7_PINCM,
        .adcInputPinMux       = CONFIG_GPIO_ADC_0_AIN7_PINMUX,
        .adcPosRefDIO         = GPIO_INVALID_INDEX,
        .adcNegRefDIO         = GPIO_INVALID_INDEX,
        .adcChannel           = 7,
        .refSource            = ADCMSPM0_VDDA_REFERENCE,
        .samplingDuration     = 16,
        .refVoltage           = 3300000, /* uV */
        .resolutionBits       = ADCMSPM0_RESOLUTION_12_BIT,
        .adcClkkDivider       = ADCMSPM0_CLKDIV_8,
        .adcClkSelect         = ADCMSPM0_CLK_ULPCLK,
        .adcClkFreqRange      = ADCMSPM0_CLK_FREQ_RANGE_24TO32,
        .conversionMode       = ADCMSPM0_SINGLE_CH_SINGLE_CONV,
        .conversionStartAddr  = 0,
        .conversionEndAddr    = 0,
        .repeatConversionMode = ADCMSPM0_REPEAT_MODE_ENABLED,
        .samplingMode         = ADCMSPM0_SAMPLING_MODE_AUTO,
        .sampleTrigger        = ADCMSPM0_SAMPLING_TRIG_SW,
        .conversionDataFormat = ADCMSPM0_CONV_DATA_FORMAT_UNSIGNED,
        .sampleTimerSrc       = ADCMSPM0_SAMP_TMR_SOURCE_SCOMP0,
        .conversionTrigger    = ADCMSPM0_NEXT_CONV_WITH_TRIG,
        .adcHWAveraging       = ADCMSPM0_HW_AVG_DISABLED,
        .idxMEMCTLx           = 0},
    /* ADC0 Channel 2 - A0_12 (HW_ID) */
    {.adc                     = ADC_0_INST,
        .adcInputDIO          = CONFIG_GPIO_ADC_0_AIN12,
        .adcInputPincm        = CONFIG_GPIO_ADC_0_AIN12_PINCM,
        .adcInputPinMux       = CONFIG_GPIO_ADC_0_AIN12_PINMUX,
        .adcPosRefDIO         = GPIO_INVALID_INDEX,
        .adcNegRefDIO         = GPIO_INVALID_INDEX,
        .adcChannel           = 12,
        .refSource            = ADCMSPM0_VDDA_REFERENCE,
        .samplingDuration     = 16,
        .refVoltage           = 3300000, /* uV */
        .resolutionBits       = ADCMSPM0_RESOLUTION_12_BIT,
        .adcClkkDivider       = ADCMSPM0_CLKDIV_8,
        .adcClkSelect         = ADCMSPM0_CLK_ULPCLK,
        .adcClkFreqRange      = ADCMSPM0_CLK_FREQ_RANGE_24TO32,
        .conversionMode       = ADCMSPM0_SINGLE_CH_SINGLE_CONV,
        .conversionStartAddr  = 0,
        .conversionEndAddr    = 0,
        .repeatConversionMode = ADCMSPM0_REPEAT_MODE_ENABLED,
        .samplingMode         = ADCMSPM0_SAMPLING_MODE_AUTO,
        .sampleTrigger        = ADCMSPM0_SAMPLING_TRIG_SW,
        .conversionDataFormat = ADCMSPM0_CONV_DATA_FORMAT_UNSIGNED,
        .sampleTimerSrc       = ADCMSPM0_SAMP_TMR_SOURCE_SCOMP0,
        .conversionTrigger    = ADCMSPM0_NEXT_CONV_WITH_TRIG,
        .adcHWAveraging       = ADCMSPM0_HW_AVG_DISABLED,
        .idxMEMCTLx           = 0},
    /* ADC0 Channel 3 - A0_0 (CH1_FET1_NTC) */
    {.adc                     = ADC_0_INST,
        .adcInputDIO          = CONFIG_GPIO_ADC_0_AIN0,
        .adcInputPincm        = CONFIG_GPIO_ADC_0_AIN0_PINCM,
        .adcInputPinMux       = CONFIG_GPIO_ADC_0_AIN0_PINMUX,
        .adcPosRefDIO         = GPIO_INVALID_INDEX,
        .adcNegRefDIO         = GPIO_INVALID_INDEX,
        .adcChannel           = 0,
        .refSource            = ADCMSPM0_VDDA_REFERENCE,
        .samplingDuration     = 16,
        .refVoltage           = 3300000, /* uV */
        .resolutionBits       = ADCMSPM0_RESOLUTION_12_BIT,
        .adcClkkDivider       = ADCMSPM0_CLKDIV_8,
        .adcClkSelect         = ADCMSPM0_CLK_ULPCLK,
        .adcClkFreqRange      = ADCMSPM0_CLK_FREQ_RANGE_24TO32,
        .conversionMode       = ADCMSPM0_SINGLE_CH_SINGLE_CONV,
        .conversionStartAddr  = 0,
        .conversionEndAddr    = 0,
        .repeatConversionMode = ADCMSPM0_REPEAT_MODE_ENABLED,
        .samplingMode         = ADCMSPM0_SAMPLING_MODE_AUTO,
        .sampleTrigger        = ADCMSPM0_SAMPLING_TRIG_SW,
        .conversionDataFormat = ADCMSPM0_CONV_DATA_FORMAT_UNSIGNED,
        .sampleTimerSrc       = ADCMSPM0_SAMP_TMR_SOURCE_SCOMP0,
        .conversionTrigger    = ADCMSPM0_NEXT_CONV_WITH_TRIG,
        .adcHWAveraging       = ADCMSPM0_HW_AVG_DISABLED,
        .idxMEMCTLx           = 0},
    /* ADC0 Channel 4 - A0_1 (CH1_FET2_NTC) */
    {.adc                     = ADC_0_INST,
        .adcInputDIO          = CONFIG_GPIO_ADC_0_AIN1,
        .adcInputPincm        = CONFIG_GPIO_ADC_0_AIN1_PINCM,
        .adcInputPinMux       = CONFIG_GPIO_ADC_0_AIN1_PINMUX,
        .adcPosRefDIO         = GPIO_INVALID_INDEX,
        .adcNegRefDIO         = GPIO_INVALID_INDEX,
        .adcChannel           = 1,
        .refSource            = ADCMSPM0_VDDA_REFERENCE,
        .samplingDuration     = 16,
        .refVoltage           = 3300000, /* uV */
        .resolutionBits       = ADCMSPM0_RESOLUTION_12_BIT,
        .adcClkkDivider       = ADCMSPM0_CLKDIV_8,
        .adcClkSelect         = ADCMSPM0_CLK_ULPCLK,
        .adcClkFreqRange      = ADCMSPM0_CLK_FREQ_RANGE_24TO32,
        .conversionMode       = ADCMSPM0_SINGLE_CH_SINGLE_CONV,
        .conversionStartAddr  = 0,
        .conversionEndAddr    = 0,
        .repeatConversionMode = ADCMSPM0_REPEAT_MODE_ENABLED,
        .samplingMode         = ADCMSPM0_SAMPLING_MODE_AUTO,
        .sampleTrigger        = ADCMSPM0_SAMPLING_TRIG_SW,
        .conversionDataFormat = ADCMSPM0_CONV_DATA_FORMAT_UNSIGNED,
        .sampleTimerSrc       = ADCMSPM0_SAMP_TMR_SOURCE_SCOMP0,
        .conversionTrigger    = ADCMSPM0_NEXT_CONV_WITH_TRIG,
        .adcHWAveraging       = ADCMSPM0_HW_AVG_DISABLED,
        .idxMEMCTLx           = 0},
    /* ADC0 Channel 5 - A0_2 (CH2_FET1_NTC) */
    {.adc                     = ADC_0_INST,
        .adcInputDIO          = CONFIG_GPIO_ADC_0_AIN2,
        .adcInputPincm        = CONFIG_GPIO_ADC_0_AIN2_PINCM,
        .adcInputPinMux       = CONFIG_GPIO_ADC_0_AIN2_PINMUX,
        .adcPosRefDIO         = GPIO_INVALID_INDEX,
        .adcNegRefDIO         = GPIO_INVALID_INDEX,
        .adcChannel           = 2,
        .refSource            = ADCMSPM0_VDDA_REFERENCE,
        .samplingDuration     = 16,
        .refVoltage           = 3300000, /* uV */
        .resolutionBits       = ADCMSPM0_RESOLUTION_12_BIT,
        .adcClkkDivider       = ADCMSPM0_CLKDIV_8,
        .adcClkSelect         = ADCMSPM0_CLK_ULPCLK,
        .adcClkFreqRange      = ADCMSPM0_CLK_FREQ_RANGE_24TO32,
        .conversionMode       = ADCMSPM0_SINGLE_CH_SINGLE_CONV,
        .conversionStartAddr  = 0,
        .conversionEndAddr    = 0,
        .repeatConversionMode = ADCMSPM0_REPEAT_MODE_ENABLED,
        .samplingMode         = ADCMSPM0_SAMPLING_MODE_AUTO,
        .sampleTrigger        = ADCMSPM0_SAMPLING_TRIG_SW,
        .conversionDataFormat = ADCMSPM0_CONV_DATA_FORMAT_UNSIGNED,
        .sampleTimerSrc       = ADCMSPM0_SAMP_TMR_SOURCE_SCOMP0,
        .conversionTrigger    = ADCMSPM0_NEXT_CONV_WITH_TRIG,
        .adcHWAveraging       = ADCMSPM0_HW_AVG_DISABLED,
        .idxMEMCTLx           = 0},
    /* ADC0 Channel 6 - A0_3 (CH2_FET2_NTC) */
    {.adc                     = ADC_0_INST,
        .adcInputDIO          = CONFIG_GPIO_ADC_0_AIN3,
        .adcInputPincm        = CONFIG_GPIO_ADC_0_AIN3_PINCM,
        .adcInputPinMux       = CONFIG_GPIO_ADC_0_AIN3_PINMUX,
        .adcPosRefDIO         = GPIO_INVALID_INDEX,
        .adcNegRefDIO         = GPIO_INVALID_INDEX,
        .adcChannel           = 3,
        .refSource            = ADCMSPM0_VDDA_REFERENCE,
        .samplingDuration     = 16,
        .refVoltage           = 3300000, /* uV */
        .resolutionBits       = ADCMSPM0_RESOLUTION_12_BIT,
        .adcClkkDivider       = ADCMSPM0_CLKDIV_8,
        .adcClkSelect         = ADCMSPM0_CLK_ULPCLK,
        .adcClkFreqRange      = ADCMSPM0_CLK_FREQ_RANGE_24TO32,
        .conversionMode       = ADCMSPM0_SINGLE_CH_SINGLE_CONV,
        .conversionStartAddr  = 0,
        .conversionEndAddr    = 0,
        .repeatConversionMode = ADCMSPM0_REPEAT_MODE_ENABLED,
        .samplingMode         = ADCMSPM0_SAMPLING_MODE_AUTO,
        .sampleTrigger        = ADCMSPM0_SAMPLING_TRIG_SW,
        .conversionDataFormat = ADCMSPM0_CONV_DATA_FORMAT_UNSIGNED,
        .sampleTimerSrc       = ADCMSPM0_SAMP_TMR_SOURCE_SCOMP0,
        .conversionTrigger    = ADCMSPM0_NEXT_CONV_WITH_TRIG,
        .adcHWAveraging       = ADCMSPM0_HW_AVG_DISABLED,
        .idxMEMCTLx           = 0},
    /* CONFIG_ADC_1 */
    {.adc                     = ADC_1_INST,
        .adcInputDIO          = CONFIG_GPIO_ADC_1_AIN,
        .adcInputPincm        = CONFIG_GPIO_ADC_1_AIN_PINCM,
        .adcInputPinMux       = CONFIG_GPIO_ADC_1_AIN_PINMUX,
        .adcPosRefDIO         = GPIO_INVALID_INDEX,
        .adcNegRefDIO         = GPIO_INVALID_INDEX,
        .adcChannel           = 2,
        .refSource            = ADCMSPM0_VDDA_REFERENCE,
        .samplingDuration     = 16,
        .refVoltage           = 3300000, /* uV */
        .resolutionBits       = ADCMSPM0_RESOLUTION_12_BIT,
        .adcClkkDivider       = ADCMSPM0_CLKDIV_8,
        .adcClkSelect         = ADCMSPM0_CLK_SYSOSC,
        .adcClkFreqRange      = ADCMSPM0_CLK_FREQ_RANGE_24TO32,
        .conversionMode       = ADCMSPM0_SINGLE_CH_SINGLE_CONV,
        .conversionStartAddr  = 0,
        .conversionEndAddr    = 0,
        .repeatConversionMode = ADCMSPM0_REPEAT_MODE_ENABLED,
        .samplingMode         = ADCMSPM0_SAMPLING_MODE_AUTO,
        .sampleTrigger        = ADCMSPM0_SAMPLING_TRIG_SW,
        .conversionDataFormat = ADCMSPM0_CONV_DATA_FORMAT_UNSIGNED,
        .sampleTimerSrc       = ADCMSPM0_SAMP_TMR_SOURCE_SCOMP0,
        .conversionTrigger    = ADCMSPM0_NEXT_CONV_WITH_TRIG,
        .adcHWAveraging       = ADCMSPM0_HW_AVG_DISABLED,
        .idxMEMCTLx           = 0},
    /* Additional ADC0 Channels */
};

/*
 *  ======== ADC_config ========
 */
const ADC_Config ADC_config[CONFIG_ADC_COUNT] = {
    /* CONFIG_ADC_0 - Main ADC0 instance (A0_7 - AMP_ID) */
    {.fxnTablePtr = &ADCMSPM0_fxnTable,
        .object   = &adcObjects[CONFIG_ADC_0],
        .hwAttrs  = &adcHWAttrs[CONFIG_ADC_0]},
    /* CONFIG_ADC_1 */
    {.fxnTablePtr = &ADCMSPM0_fxnTable,
        .object   = &adcObjects[CONFIG_ADC_1],
        .hwAttrs  = &adcHWAttrs[CONFIG_ADC_1]},
    /* Additional ADC0 Channels */
    /* CONFIG_ADC_2 - A0_12 (HW_ID) */
    {.fxnTablePtr = &ADCMSPM0_fxnTable,
        .object   = &adcObjects[CONFIG_ADC_2],
        .hwAttrs  = &adcHWAttrs[CONFIG_ADC_2]},
    /* CONFIG_ADC_3 - A0_0 (CH1_FET1_NTC) */
    {.fxnTablePtr = &ADCMSPM0_fxnTable,
        .object   = &adcObjects[CONFIG_ADC_3],
        .hwAttrs  = &adcHWAttrs[CONFIG_ADC_3]},
    /* CONFIG_ADC_4 - A0_1 (CH1_FET2_NTC) */
    {.fxnTablePtr = &ADCMSPM0_fxnTable,
        .object   = &adcObjects[CONFIG_ADC_4],
        .hwAttrs  = &adcHWAttrs[CONFIG_ADC_4]},
    /* CONFIG_ADC_5 - A0_2 (CH2_FET1_NTC) */
    {.fxnTablePtr = &ADCMSPM0_fxnTable,
        .object   = &adcObjects[CONFIG_ADC_5],
        .hwAttrs  = &adcHWAttrs[CONFIG_ADC_5]},
    /* CONFIG_ADC_6 - A0_3 (CH2_FET2_NTC) */
    {.fxnTablePtr = &ADCMSPM0_fxnTable,
        .object   = &adcObjects[CONFIG_ADC_6],
        .hwAttrs  = &adcHWAttrs[CONFIG_ADC_6]},
    /* CONFIG_ADC_7 - Additional ADC0 channel placeholder */
    {.fxnTablePtr = &ADCMSPM0_fxnTable,
        .object   = &adcObjects[CONFIG_ADC_7],
        .hwAttrs  = &adcHWAttrs[CONFIG_ADC_7]},
};

const uint_least8_t CONFIG_ADC_0_CONST = CONFIG_ADC_0;
const uint_least8_t CONFIG_ADC_1_CONST = CONFIG_ADC_1;
const uint_least8_t CONFIG_ADC_2_CONST = CONFIG_ADC_2;
const uint_least8_t CONFIG_ADC_3_CONST = CONFIG_ADC_3;
const uint_least8_t CONFIG_ADC_4_CONST = CONFIG_ADC_4;
const uint_least8_t CONFIG_ADC_5_CONST = CONFIG_ADC_5;
const uint_least8_t CONFIG_ADC_6_CONST = CONFIG_ADC_6;
const uint_least8_t CONFIG_ADC_7_CONST = CONFIG_ADC_7;
const uint_least8_t ADC_count          = CONFIG_ADC_COUNT;

/*
 *  =============================== UART0 ===============================
 */
#include <ti/drivers/uart/UARTMSPM0.h>

static const UARTMSP_HWAttrs UARTMSPHWAttrs[CONFIG_UART_COUNT] = {
    {
        .regs          = UART0,
        .irq           = UART0_INT_IRQn,
        .rxPin         = IOMUX_PINCM22, /* PA11 */
        .rxPinFunction = IOMUX_PINCM22_PF_UART0_RX,
        .txPin         = IOMUX_PINCM21, /* PA10 */
        .txPinFunction = IOMUX_PINCM21_PF_UART0_TX,
        .mode          = DL_UART_MODE_NORMAL,
        .direction     = DL_UART_DIRECTION_TX_RX,
        .flowControl   = DL_UART_FLOW_CONTROL_NONE,
        .clockSource   = DL_UART_CLOCK_BUSCLK,
        .clockDivider  = DL_UART_CLOCK_DIVIDE_RATIO_4,
        .rxIntFifoThr  = DL_UART_RX_FIFO_LEVEL_ONE_ENTRY,
        .txIntFifoThr  = DL_UART_TX_FIFO_LEVEL_EMPTY,
    },
    {
        .regs          = UART1,
        .irq           = UART1_INT_IRQn,
        .rxPin         = IOMUX_PINCM20, /* PA9 */
        .rxPinFunction = IOMUX_PINCM20_PF_UART1_RX,
        .txPin         = IOMUX_PINCM19, /* PA8 */
        .txPinFunction = IOMUX_PINCM19_PF_UART1_TX,
        .mode          = DL_UART_MODE_NORMAL,
        .direction     = DL_UART_DIRECTION_TX_RX,
        .flowControl   = DL_UART_FLOW_CONTROL_NONE,
        .clockSource   = DL_UART_CLOCK_BUSCLK,
        .clockDivider  = DL_UART_CLOCK_DIVIDE_RATIO_4,
        .rxIntFifoThr  = DL_UART_RX_FIFO_LEVEL_ONE_ENTRY,
        .txIntFifoThr  = DL_UART_TX_FIFO_LEVEL_EMPTY,
    },
};

UART_Data_Object UARTObject[CONFIG_UART_COUNT] = {
    {
        .object =
            {
                .supportFxns        = &UARTMSPSupportFxns,
                .buffersSupported   = true,
                .eventsSupported    = false,
                .callbacksSupported = false,
                .dmaSupported       = false,
                .noOfDMAChannels    = 0,
            },
        .buffersObject =
            {
                .rxBufPtr  = rxBuffer,
                .txBufPtr  = txBuffer,
                .rxBufSize = sizeof(rxBuffer),
                .txBufSize = sizeof(txBuffer),
            },
    },
    {
        .object =
            {
                .supportFxns        = &UARTMSPSupportFxns,
                .buffersSupported   = true,
                .eventsSupported    = false,
                .callbacksSupported = false,
                .dmaSupported       = false,
                .noOfDMAChannels    = 0,
            },
        .buffersObject =
            {
                .rxBufPtr  = rxBuffer,
                .txBufPtr  = txBuffer,
                .rxBufSize = sizeof(rxBuffer),
                .txBufSize = sizeof(txBuffer),
            },
    },
};

const UART_Config UART_config[CONFIG_UART_COUNT] = {
    {
        &UARTObject[CONFIG_UART_0],
        &UARTMSPHWAttrs[CONFIG_UART_0],
    },
    {
        &UARTObject[CONFIG_UART_1],
        &UARTMSPHWAttrs[CONFIG_UART_1],
    },
};

void UART0_IRQHandler(void)
{
    UARTMSP_interruptHandler((UART_Handle) &UART_config[CONFIG_UART_0]);
}

void UART1_IRQHandler(void)
{
    UARTMSP_interruptHandler((UART_Handle) &UART_config[CONFIG_UART_1]);
}

void UARTMSP_eventCallback(
    UART_Handle handle, uint32_t event, uint32_t data, void *userArg)
{
}
ti_drivers_config.h

  • Here are logs for your reference.


    [DBG] ADC0_7(AMP_ID)[2979]: min=0, max=24, avg=6 (0.0048 V)
    [DBG] ADC0_12(HW_ID)[2979]: min=36, max=94, avg=63 (0.0507 V)
    [DBG] ADC0_0(CH1_FET1_NTC)[2979]: min=104, max=155, avg=128 (0.1031 V)
    [DBG] ADC0_1(CH1_FET2_NTC)[2979]: min=161, max=209, avg=184 (0.1482 V)
    [DBG] ADC0_2(CH2_FET1_NTC)[2979]: min=211, max=256, avg=233 (0.1877 V)
    [DBG] ADC0_3(CH2_FET2_NTC)[2979]: min=732, max=902, avg=834 (0.6720 V)
    [DBG] ADC1[2979]: min=250, max=293, avg=271 (0.2183 V)
    [DBG] ----------------------

  • Hi, it seems that you are using freertos, correct?

    When 3.3V is connected to PA22, all ADC readings are affected except for ADC0_3.

    What's kind of affection do you seen?

    When 3.3V is connected to PA17, ADC0_3 shows a reading.

    Is this behavior abnormal? Could you explain it carefully for "shows a reading" action?

    The pin-to-channel mapping is as follows:

    Do you enable any other analog peripherals in your application code?

    When 3.3V is connected to PA15, no effect is observed.

    It seems there are issues seen from ADC0 and there is no issue from ADC1.

    Please help to confirm all abnormal phenomenon is test only use ADC and no other peripherals are used.

    2210.adc12_sequence_DMA_G3507.zip

    Here is an ADC code example in sequence mode and using DMA to carry the ADC result, please help to address the issue by using this example.

    It a simple ADC example.

    How many chips do you test? What is the probability of ADC0 issue?

  • Hi Helic,

    Thank you for your response.

    To clarify your earlier questions:

    • Yes, we are using FreeRTOS.

    • The issue is abnormal ADC behavior:

      • When 3.3V is applied to PA22, channels ADC0_7 (AMP_ID), ADC0_12 (HW_ID), ADC0_0 (CH1_FET1_NTC), ADC0_1 (CH1_FET2_NTC), and ADC1 all read 3.3V, but ADC0_2 (CH2_FET1_NTC) reads only around 0.6V.

      • Similarly, when 3.3V is applied to PA17, only ADC0_3 shows 3.3V, while other channels read approximately 0.04V.

    • No other analog peripherals are enabled in the application code.

    • We tested two LP-MSPM0G3507 development kits, and both exhibit the same issue.

    Regarding the sample code you shared (2210.adc12_sequence_DMA_G3507.zip), it is based on the driver library rather than the TI driver model. Since our project is built on the TI drivers, this example isn’t directly applicable.

    We would appreciate your further guidance on resolving this ADC behavior in a TI driver-based RTOS environment.

    Best regards,
    Pakho.

  • Regarding the sample code you shared (2210.adc12_sequence_DMA_G3507.zip), it is based on the driver library rather than the TI driver model. Since our project is built on the TI drivers, this example isn’t directly applicable.

    This is the easiest way to separate hardware/software issues.

    If the test results point to software, we can continue debug the software.

    Could you please help to test this demo code from your side?

  • Hi Helic,

    I tested this demo. It works. I found that PA27 and PA22 affect each other.

  • What's the correct value of PA27 and PA22?

    I will try this setup at my side.

  • Hi Helic,

    We are observing significant signal cross-talk between ADC pins PA22 and PA27 during our tests.

    The abnormal behavior is as follows:

    1. When 3.3V is applied to PA22, the ADC reading on the disconnected PA27 is approximately 3875 (on a 12-bit scale), instead of the expected value near 0.

    2. Conversely, when 3.3V is applied to PA27, the reading on the disconnected PA22 is approximately 3890, again instead of a value near 0.

    This indicates a clear and consistent cross-talk issue between these two input channels. We have verified this behavior on both of our LP-MSPM0G3507 development kits.

    Could you please advise on the potential root cause and any possible solutions to isolate these ADC channels effectively?

    Best regards,

    Pakho.

  • Hi,  

    Could you please send me your MSPM0 package information?

    Better to have OPN of your M0.(Part number + package)

  • Hi Helic,

    Here is the package information for your reference.

  • The abnormal behavior is as follows:

    1. When 3.3V is applied to PA22, the ADC reading on the disconnected PA27 is approximately 3875 (on a 12-bit scale), instead of the expected value near 0.

    2. Conversely, when 3.3V is applied to PA27, the reading on the disconnected PA22 is approximately 3890, again instead of a value near 0.

    I got this crosstalk test result.

    1. Could you please test the below condition?

    Input a sin waveform to a ADC pin Channel x, and ADC samples this pin channel x periodically.

    Then monitor another ADC pin Channel y, Channel y doesn't need to config it, leave it unconnected and connect to oscilloscope to monitor the signal.

    Try to find all related crosstalk between x and y, x could be PA22 and y could be PA27, any available ADC input pin.

    2. Need to confirm how do you get these MSPM0 chips? but from ti.com or ti samples or buy from 3rd vendor?

  • 2. Need to confirm how do you get these MSPM0 chips? but from ti.com or ti samples or buy from 3rd vendor?

    It should be ti samples.

  • It should be ti samples.

    Request some new one~

    It should be worked.

  • Hi  ,

    Back to the beginning.

    I have encountered a configuration issue with the ADC settings in the ti_drivers_config.c file.

    Issue:
    I've identified that the problem lies in the const ADCMSPM0_HWAttrs adcHWAttrs configuration within ti_drivers_config.c. The current SDK examples primarily demonstrate single conversion mode, but I need to configure the ADC for sequence mode operation.

    Specific Request:
    I would like to add an additional channel (PA14, A0_12) to ADC0 and configure it for sequence mode operation. Could you please help me understand what parameters need to be modified in the adcHWAttrs structure to achieve this?

    Current Configuration Snippet:

    const ADCMSPM0_HWAttrs adcHWAttrs[CONFIG_ADC_COUNT] = {
        /* CONFIG_ADC_0 */
        {.adc                     = ADC_0_INST,
            .adcInputDIO          = CONFIG_GPIO_ADC_0_AIN,
            .adcInputPincm        = CONFIG_GPIO_ADC_0_AIN_PINCM,
            .adcInputPinMux       = CONFIG_GPIO_ADC_0_AIN_PINMUX,
            .adcPosRefDIO         = GPIO_INVALID_INDEX,
            .adcNegRefDIO         = GPIO_INVALID_INDEX,
            .adcChannel           = 7,
            .refSource            = ADCMSPM0_VDDA_REFERENCE,
            .samplingDuration     = 16,
            .refVoltage           = 3300000, /* uV */
            .resolutionBits       = ADCMSPM0_RESOLUTION_12_BIT,
            .adcClkkDivider       = ADCMSPM0_CLKDIV_8,
            .adcClkSelect         = ADCMSPM0_CLK_ULPCLK,
            .adcClkFreqRange      = ADCMSPM0_CLK_FREQ_RANGE_24TO32,
            .conversionMode       = ADCMSPM0_SINGLE_CH_SINGLE_CONV,
            .conversionStartAddr  = 0,
            .conversionEndAddr    = 0,
            .repeatConversionMode = ADCMSPM0_REPEAT_MODE_ENABLED,
            .samplingMode         = ADCMSPM0_SAMPLING_MODE_AUTO,
            .sampleTrigger        = ADCMSPM0_SAMPLING_TRIG_SW,
            .conversionDataFormat = ADCMSPM0_CONV_DATA_FORMAT_UNSIGNED,
            .sampleTimerSrc       = ADCMSPM0_SAMP_TMR_SOURCE_SCOMP0,
            .conversionTrigger    = ADCMSPM0_NEXT_CONV_WITH_TRIG,
            .adcHWAveraging       = ADCMSPM0_HW_AVG_DISABLED,
            .idxMEMCTLx           = 0},
        /* CONFIG_ADC_1 */
    }

    Questions:

    1. What parameters need to be modified to change from single conversion mode to sequence mode?

    2. How should I configure the start and end addresses for the conversion sequence?

    3. Are there any specific considerations for the sampling timer source or trigger settings when using sequence mode?

    4. How do I properly set up the memory control registers (MEMCTLx) for multiple channels in sequence mode?

    I would greatly appreciate your guidance on the specific modifications needed in the adcHWAttrs structure to enable sequence mode with multiple channels, particularly for adding PA14 (A0_12) to ADC0.

    Thank you for your assistance.

    Best regards,

    Thanks.

    Pakho
  • Let's talk this ADC config question in the other threads.

    It seems this thread is mainly talk about the ADC crosstalk.

  • I have connected a 3.3V input signal to PA22, but I am measuring approximately 2.9V on PA27. This voltage discrepancy suggests there may be an unexpected signal path or hardware issue on the development board.

    I will check the issue when I get the new board.

  • I will check the issue when I get the new board.

    OK, got it~