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.

AM263P4: Full ADC External Mux configuration in SysConfig

Part Number: AM263P4
Other Parts Discussed in Thread: SYSCONFIG

Tool/software:

I am attempting to use the External Mux functionality of ADC0 through SysConfig. However, it appears that the "Use External Mux" checkbox is the only option available regarding this functionality. The Technical Manual gives rough details of how to make use of the external mux, but of course does so with no references to what SysConfig will/won't be doing as part of the setup and execution. It also appears that there are no examples in the SDK that use this functionality.  I am looking for guidance on how to properly configure the ADC in SysConfig, and that what additional API commands need to be placed in code for setup and execution.

  • While researching how to connect the SOC to an external pin of the device, I noticed that the implementation of the ADC_selectSOCExtChannel in mcu_plus_sdk_am263px_10_01_00_31.  Here is the function copied from the sdk:

    static inline void
    ADC_selectSOCExtChannel(uint32_t base, ADC_SOCNumber socNumber,
                            uint16_t extChannel)
    {
        uint32_t ctlRegAddr;
    
        //
        // Check the arguments.
        //
        DebugP_assert(extChannel <= 3U);
    
        //
        // Calculate address for the SOC control register.
        //
        ctlRegAddr = base + CSL_ADC_ADCSOC0CTL +
            ((uint32_t)socNumber * ADC_ADCSOCxCTL_STEP);
    
        //
        // Set the external channel configuration of the specified SOC.
        //
        HW_WR_REG32(ctlRegAddr,
            ((HW_RD_REG32(ctlRegAddr) & ~((uint32_t)CSL_ADC_ADCSOC0CTL_EXTCHSEL_MASK)) |
            (uint32_t)extChannel));
    
    }

    and from the cslr_adc.h file:

    #define CSL_ADC_ADCSOC0CTL_EXTCHSEL_MASK                                       (0xF0000000U)

    and here is the register definition from the register addendum:

    Note that the EXTCHSEL are bits 31:28, which correlates to the value of the CSL_ADC_ADCSOC0CTL_EXTCHSEL_MASK.  However, note that the incoming extChannel value is tested in the function to be <= 3, and then directly used. Because it never gets bit shifted, it will never actually be working on the correct bits in the register.

  • Hi Nathan

    Note that the EXTCHSEL are bits 31:28, which correlates to the value of the CSL_ADC_ADCSOC0CTL_EXTCHSEL_MASK.  However, note that the incoming extChannel value is tested in the function to be <= 3, and then directly used. Because it never gets bit shifted, it will never actually be working on the correct bits in the register.

    Thank you for pointing this out, your observation looks correct, the fix:

        HW_WR_REG32(ctlRegAddr,
            ((HW_RD_REG32(ctlRegAddr) & ~((uint32_t)CSL_ADC_ADCSOC0CTL_EXTCHSEL_MASK)) |
            (((uint32_t)extChannel << CSL_ADC_ADCSOC0CTL_EXTCHSEL_SHIFT) & (uint32_t)CSL_ADC_ADCSOC0CTL_EXTCHSEL_MASK)));

    this should work, I'll confirm with the dev team and file a bug to fix this!

    Thanks & regards
    Akshit

  • Thank you for the response.  I had already made a similar modification to the code, but I am still unable to determine how to correctly get these signals mapped to output pins. Can someone please provide example code, sysconfig, or really anything that shows how to correctly setup and route these signals to a pin.

  • Hi Nathan

    To map the signals to output pins, you'll need to use ADC_EXTCH_XBAR.

    You can go through 7.5.2.9.1 External Channel Selection - TRM, to get more info!

    Regards,
    Akshit

  • I have been attempting to follow this section, but it gives extremely limited detail and has conflicting information.  No configurations I have tried are yielding a signal from the expected pins.

    check it out:

    So is it a two bit mux selection? because that doesn't match up with other information showing a 4 bit channel selection.

    and then there is this....

    How is that done? GPIO Output crossbar isn't an option in sysconfig. OUTPUT XBAR is a there, but contains no references to the ADCxEXTMUX. GPIO INT XBAR is also there, but isn't related to this task either. 

    I have followed these bare instructions:

    In my application, I am using an ADC name CONFIG_ADC1. SOC0 is setup for ADCIN0 on ADC1. the SOC trigger is set for software only. The ADC_EXTCH_XBAR is setup as follows:

    I have modified the ADC_selectSOCExtChannel() as discussed earlier. And I am using the following lines of code to setup and test this:

    ADC_selectSOCExtChannel(CONFIG_ADC1_BASE_ADDR,0,3);
    ADC_forceSOC(CONFIG_ADC1_BASE_ADDR, ADC_SOC_NUMBER0);

    I have adjusted everything I can think of, but I never get any changes on any of the pins listed in the ADC_EXTCH_XBAR.  which leads me to where I think there is a huge gap in the documentation on this. There is no documentation showing automatic mapping of the ADC_EXTCH_XBAR to the ADCxEXTMUX, and there is no documentation saying that it is needed. That doesn't really add up, since the ADC_EXTCH_XBAR has far more pins than what the ADCxEXTMUX can support. Even with what you've sent me, you aren't showing how to connect the ADC instance to the ADC_EXTCH_XBAR, which is the crux of this.

    My suspicion here is that these features aren't fully implemented, and quite possibly to the extent that the peripherals aren't actually able to be used to run an external mux from the adc.

  • Hi Nathan

    So I found another bug through sysconfig

    Checking ''Use External MUX" is calling the disable API instead of enable, we'll need to fix this, for the time could you try the enable API and let me know if anything changes.

    My suspicion here is that these features aren't fully implemented, and quite possibly to the extent that the peripherals aren't actually able to be used to run an external mux from the adc.

    I apologize for this inconvenience but your suspicion seems right, these features aren't implemented properly, I'll have a discussion with the team and escalate this issue to make sure these features are implemented properly!

    Thank you so much for your patience!

    Regards,
    Akshit

  • I had noticed the ADC ExtMuxPreselect as well. and I have experimented with the use of the ADC_enableExtMuxPreselect() function. It didn't seem to be the fix.

    It was also unclear from the documentation if this needs to be enabled. In some places it makes it sound as though the ExtMuxPreselect is optional as a way to change the mux timing to fit the ADC sampling. But in other places it makes it sounds as though it MUST be enabled, which means that when using the external ADC mux functionality, you would be forced to use the ExtMuxPreselect enabled timing.

  • Thanks for pointing this out as well Nathan.

    Please be assured, I am working with both HW and SW teams to fix this issue in SDK and documentation, we'll also try to focus on creating an example to better showcase the usage of ADC external channel selection.

    I'll get back to you tomorrow with something more useful than this, we'll fix this issue ASAP.

    Thanks & regards,
    Akshit

  • Hi Nathan

    So is it a two bit mux selection? because that doesn't match up with other information showing a 4 bit channel selection.

    The ADC wrapper instance does provide 4 bits of EXTCHSEL, however, in AM263p, only the 2 LSBs are connected to the pinmux i.e. this register is [3:0]... but the valid bits are only 2 LSB.. i.e., [1:0] is connected to the pinmux

    We'll add this to the TRM.

    We are also in the process of creating a demo example for using an ext channel. I'll get back to you with that ASAP.

    I'll be following this process:

    The ADC_EXTCH_XBAR[9:0] outputs can be mapped to GPIO by configuring the associated IOMUX to use the ADC_EXTCH_XBAR signal accordingly. the EXTCHSEL field in ADCs supports up to 2 bit signals, but fewer mux selection output pins can be configured if desired.
    
    Each ADC can send upto 2 signals to the internal ADCEXTCHSELy muxes, the configurations for which are present in the Global Control Registers. ADCEXTCHSELy (y = 0-9)  correspond to the ADC_EXTCH_XBARy outputs. the registers ADCEXTCHSELy[3:0] select which EXTCHSEL signal from each ADC to be passed on to the ADC_EXTCH_XBARy. The IOMUX that selects and outputs ADC_EXTCH_XBARy can be used either individually or grouped to configure the external muxes.
    
    To select a specific channel on the external mux.., 
        1. configure ADCSOCxCTRL.CHSEL to select the ADC pin that is connected to the mux output. 
        2. the ADCEXTCHSELy maps the signals from ADCs' EXTCHSEL signals to the ADC_EXTCH_XBARy outputs. Configure ADCEXTCHSELy in the Global Control Regs to pass these ADCSOCxEXTCHSEL signals.
        3. Once, the IOMUX is configured to use the ADC_EXTCH_XBAR signals, and an SOC that is configured with EXTCHSEL and ADCEXTCHSELx at Global Registers is triggered, this signal goes through to the IO to the external muxes.
     

    Thank you so much for your patience!

    Regards,
    Akshit

  • Hi Nathan

    Please refer to the following example to get ADC_EXTCH selection functionality working.

    Here, I am using the fixed API:

    static inline void
    App_ADC_selectSOCExtChannel(uint32_t base, ADC_SOCNumber socNumber,
                            uint16_t extChannel)
    {
        uint32_t ctlRegAddr;
    
        //
        // Check the arguments.
        //
        DebugP_assert(extChannel <= 3U);
    
        //
        // Calculate address for the SOC control register.
        //
        ctlRegAddr = base + CSL_ADC_ADCSOC0CTL +
            ((uint32_t)socNumber * ADC_ADCSOCxCTL_STEP);
    
        //
        // Set the external channel configuration of the specified SOC.
        //
        // HW_WR_REG32(ctlRegAddr,
        //     ((HW_RD_REG32(ctlRegAddr) & ~((uint32_t)CSL_ADC_ADCSOC0CTL_EXTCHSEL_MASK)) |
        //     (uint32_t)extChannel));
        HW_WR_REG32(ctlRegAddr,
            ((HW_RD_REG32(ctlRegAddr) & ~((uint32_t)CSL_ADC_ADCSOC0CTL_EXTCHSEL_MASK)) |
            (((uint32_t)extChannel << CSL_ADC_ADCSOC0CTL_EXTCHSEL_SHIFT) & (uint32_t)CSL_ADC_ADCSOC0CTL_EXTCHSEL_MASK)));
    
    }

    Calling the API in the main function, with SOC0 configured and desired external channel as '2':

    App_ADC_selectSOCExtChannel(baseAddr, ADC_SOC_NUMBER0, ADC_CH_ADCINX_2);

    Then I call the following API's:

    SOC_selectAdcExtChXbar(0, ADC1_EXTCHSEL_BIT0); //ADC1 is selected in sysconfig
    SOC_selectAdcExtChXbar(1, ADC1_EXTCHSEL_BIT1);

    The SOC_selectAdcExtChXbar(uint32_t extChXbarOut, uint32_t extChXbarIn) API selects the ADC External Channel Select bit for the output from each xbar out. This is most likely the missing step in you configuration as well.

    This API configures the external channel crossbar (XBAR) for ADC inputs, allowing you to:

    1. Select which ADC input pins are connected to external multiplexers
    2. Configure the routing between ADC external channel selection bits and GPIO pins
    The ADC_EXTCH_XBAR in sysconfig is selected (This is only setting the correct pinmux for pins to get ADC ext select lines on)
    Now when I run the program, we can see the ext channel 2 line go up on C14
    To showcase it is working properly, now if I force on SOC2 instead:
    We can see the line reset to 0 for ext channel 2 on C14
    Similarly, if I want the desired external channel to be 3.
    App_ADC_selectSOCExtChannel(baseAddr, ADC_SOC_NUMBER0, ADC_CH_ADCINX_3);
    I can see channel 3 selected on C13 and C14.
    Attaching the reference project for your perusal!
    Let me know if this helps solve your issue!
    Best Regards,
    Akshit
  • Hello Akshit,

        Using the SOC_selectAdcExtChXbar(uint32_t extChXbarOut, uint32_t extChXbarIn) API was the missing piece I needed. After modifying the App_ADC_selectSOCExtChannel() function and using the SOC_selectAdcExtChXbar, I am able to successfully see a change on the output pins as expected.

        I was also able to answer my other question. It appears that the external channel configuration is unique to each ADC instance. This allows me to configure multiple ADC instances to use ADC External Mux configurations, and then map each instance to unique pins on the ADC_EXTCH_XBAR.  Thank you for your assistance in this.