Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Not applicable
Need to convert P2_0, P2_1 and P2_2 continuously and have an interrupt at the end of the conversion of all three.

There are no examples in the xmclibs, well there is for the XMC1200, but this is not compatible with XMC1100, compiler complains about fields in the configuration structures.

Look forward to a speedy resolution 🙂
0 Likes
8 Replies
lock attach
Attachments are accessible only for community members.
Travis
Employee
Employee
First solution authored Welcome! 500 replies posted
Hi,

Can you give this a try? Please take note that this example is for AB step.
0 Likes
Not applicable
Travis wrote:
Hi,

Can you give this a try? Please take note that this example is for AB step.


Why have you just sent me a generic example, and without even testing it........

Like i said the examples are for the XMC1200, and they are not compatible.

The compiler complains about some of the struct fields, see bold text i.e.


const XMC_VADC_GLOBAL_CONFIG_t g_global_handle =
{
.disable_sleep_mode_control = false,

.clock_config = {
.analog_clock_divider= 3,
.msb_conversion_clock= 0,
.arbiter_clock_divider= 1
},

.class0 = {
.conversion_mode_standard= XMC_VADC_CONVMODE_12BIT,
.sample_time_std_conv = 3U,
.conversion_mode_emux= XMC_VADC_CONVMODE_12BIT,
.sampling_phase_emux_channel = 3U
},

.class1 = {
.conversion_mode_standard= XMC_VADC_CONVMODE_12BIT,
.sample_time_std_conv= 3U,
.conversion_mode_emux= XMC_VADC_CONVMODE_12BIT,
.sampling_phase_emux_channel= 3U
},


emux is not support by XMC1100 so i dont know why you have even sent these examples lol.....



Please can you send me a tested example on a XMC1100 bootkit.
0 Likes
Not applicable
Tabulous,

The XMC1100 does not have the complete VADC hardware that the 1200, 1300, 1400, and 4X00 have. Not only does the XMC1100 does not have a FIFO, it also lacks DMA. It has a single 32-bit result buffer. I am confident one cannot have a single interrupt that provides all three conversions. The 1200, 1300, and on up have a 8 X 32-bit result FIFO that will easily allow you to have a single interrupt with all the converted data. I am currently using the 1100 converting two analog signals and I have two back-to-back interrupts.

Steve.
0 Likes
Not applicable
smays wrote:
Tabulous,

The XMC1100 does not have the complete VADC hardware that the 1200, 1300, 1400, and 4X00 have. Not only does the XMC1100 does not have a FIFO, it also lacks DMA. It has a single 32-bit result buffer. I am confident one cannot have a single interrupt that provides all three conversions. The 1200, 1300, and on up have a 8 X 32-bit result FIFO that will easily allow you to have a single interrupt with all the converted data. I am currently using the 1100 converting two analog signals and I have two back-to-back interrupts.

Steve.


Hi Steve,
thanks for the comments back. Having a single interrupt per conversion is ok, but its the fact that there are no examples for the XMC1100 based on the xmclibs that is very frustrating.

Why Travis has suggested using an example for a XMC1200 when they know full well it will not work is beyond me lol
0 Likes
Not applicable
...I am trying to not give Travis, et al, any grief. At least Infineon Employees participate in these forums, as opposed to M****Ch**. That said, available ADC code for the XMC1100 is virtually non-existent. Infineon has genuinely dropped the ball regarding code example support for the XMC1100 series. A pro and simultaneously a con of Infineon's VADC hardware is the fact it is practically identical for the 1200 and up. The crappy con is the stupid fact the subtle differences of the watered down ADC of the 1100 prevent one from using the cornucopia of 1200 and up examples.

I have code I would be glad to share, but for the very most part I ONLY access the registers directly and I do not use XMCLIB. I plan to rid myself of the three XMCLIB calls my code makes as soon as I get back to the XMC1100 portion of my current project.

Steve.
0 Likes
Not applicable
smays wrote:
...I am trying to not give Travis, et al, any grief. At least Infineon Employees participate in these forums, as opposed to M****Ch**. That said, available ADC code for the XMC1100 is virtually non-existent. Infineon has genuinely dropped the ball regarding code example support for the XMC1100 series. A pro and simultaneously a con of Infineon's VADC hardware is the fact it is practically identical for the 1200 and up. The crappy con is the stupid fact the subtle differences of the watered down ADC of the 1100 prevent one from using the cornucopia of 1200 and up examples.

I have code I would be glad to share, but for the very most part I ONLY access the registers directly and I do not use XMCLIB. I plan to rid myself of the three XMCLIB calls my code makes as soon as I get back to the XMC1100 portion of my current project.

Steve.


Hi Steve,
any help even low level register setup would be good 🙂

Cheers
0 Likes
Not applicable
Travis, would you care to comment on the lack of application examples for the XMC1100 ?
0 Likes
Not applicable
Sorry, I forgot all about this. I go through great pains to make sure my code is formatted just the way I think it should be, but this forum will not preserve my careful and purposeful formatting.
(As I organize my code...)


In your header file (PeripheralSetup.h):

#include "Libraries\CMSIS\Infineon\XMC1100_series\Include\XMC1100.h"

#define XMC_VADC_CONV_ENABLE_FOR_XMC11 (*(uint32_t*) 0x40010500UL)

void InitializeADC(void);
void InitializeCCU4_Slice2TimerForADC(unsigned short usUpdatePeriod);
void InitializeMainSystemClock(void);
void PrepCCU4(void);



In your source file (PeripheralSetup.c):

void InitializeMainSystemClock(void)
{
SCU_GENERAL->PASSWD = 0x000000C0UL; // disable bit protection
SCU_CLK->CLKCR = 0x3FF10100UL; // MCLK = 32MHz, PCLK = 64MHz
while((SCU_CLK->CLKCR & SCU_CLK_CLKCR_VDDC2LOW_Msk));
SCU_GENERAL->PASSWD = 0x000000C3UL; // enable bit protection
SystemCoreClockUpdate();
}
void InitializeGPIO()
{
PORT2->IOCR0 &= ~PORT2_IOCR0_PC0_Msk; // Set P2.0 as Direct Input: No internal pull device active by setting all P2.0 bits to zero.
PORT2->IOCR4 &= ~PORT2_IOCR4_PC6_Msk; // Set P2.6 as Direct Input: No internal pull device active by setting all P2.6 bits to zero.
PORT2->PDISC = 0x41; //Disable Digital Input Pull Up for P2.0 and P2.6
}
void PrepCCU4(void)
{
SCU_GENERAL->PASSWD = 0x000000C0UL; // disable bit protection
SCU_CLK->CGATCLR0 |= (1 << SCU_CLK_CGATCLR0_CCU40_Pos);
SCU_GENERAL->PASSWD = 0x000000C3UL; // enable bit protection
// Set Prescaler run bit
CCU40->GIDLC |= (1 << CCU4_GIDLC_SPRB_Pos); // Prescaler Run Bit Set: Writing a 1B into this register sets the Run Bit of the prescaler.
//Set GCTRL to Default status
CCU40->GCTRL = 0x00000000UL; // MSDE (bits 15-14) = MSE3 (bit 13) = MSE2 (bit 13) = MSE1 (bit 13) = MSE0 (bit 13) = SUSCFG (bits 9-8) = PCIS (bits 5-4) = PRBC (bits 2-0) = 0
}
void InitializeCCU4_Slice2TimerForADC(unsigned short usUpdatePeriod)
{
CCU40_CC42->INS = (8 << CCU4_CC4_INS_EV0IS_Pos) //Map CCU40.IN0I, Global Enable
| (1 << CCU4_CC4_INS_EV0EM_Pos); //Set for Rising Edge Detection

CCU40_CC42->CMC = (1 << CCU4_CC4_CMC_STRTS_Pos); //Externally started from Global Enable

CCU40_CC42->CRS = ((usUpdatePeriod >> 1) << CCU4_CC4_CRS_CRS_Pos);
CCU40_CC42->PRS = (usUpdatePeriod << CCU4_CC4_PRS_PRS_Pos);

CCU40->GCSS |= (1 << CCU4_GCSS_S2SE_Pos); //S2SE, Slice 2 shadow transfer set enable.

CCU40_CC42->INTE = (1 << CCU4_CC4_INTE_CMUE_Pos); //Set Compare Match Flag for Routing to Service Bit
CCU40_CC42->SRS = (3 << CCU4_CC4_SRS_CMSR_Pos); //Set Compare Match to SR2 Service Bit (CCU40.SR2 --> VADC0.G0REQTRA)

CCU40->GIDLC |= (1 << CCU4_GIDLC_CS2I_Pos);
}
void InitializeADC()
{
unsigned int uiSHS0_Value;

// Disable clock gating to VADC
SCU_GENERAL->PASSWD = 0x000000C0UL; // disable bit protection
SCU_CLK->CGATCLR0 |= SCU_CLK_CGATCLR0_VADC_Msk;
while((SCU_CLK->CLKCR)&0x40000000); // wait for VDDC to stabilize
SCU_GENERAL->PASSWD = 0x000000C3UL; // enable bit protection

//GLOBAL VADC INITIALIZATION
VADC->CLC = (0 << VADC_CLC_DISR_Pos) // (DISR, bit 0) Module Disable Request Bit: 0B On request: enable the module clock
| (0 << VADC_CLC_DISS_Pos) // (DISS, bit 1) Module Disable Status Bit: 0B Module clock is enabled
| (0 << VADC_CLC_EDIS_Pos); // (EDIS, bit 3) Sleep Mode Enable Control: 0B Sleep mode request is enabled and functional
while(VADC->CLC != 0);

/* Enabling the Analog part of the converter*/
uiSHS0_Value = SHS0->SHSCFG | SHS_SHSCFG_SCWC_Msk;
uiSHS0_Value &= ~(SHS_SHSCFG_ANOFF_Msk);
SHS0->SHSCFG = uiSHS0_Value;

XMC_VADC_CONV_ENABLE_FOR_XMC11 = 1U;

// Initiate start up calibration
VADC->GLOBCFG = (1 << VADC_GLOBCFG_SUCAL_Pos);

VADC->BRSCTRL = (0b0001 << VADC_BRSCTRL_XTSEL_Pos) // (XTSEL, bits 8-11) External Trigger Input Selection: Set Trigger to VADC.BGREQTRA ('0') for Connection to CCU40.SR2,
| (0b10 << VADC_BRSCTRL_XTMODE_Pos) // (XTMODE, bit 13-14) Trigger Operating Mode: 0b10 = Trigger on Rising Edge
| (0b1 << VADC_BRSCTRL_XTWC_Pos); // (XTWC, bit 15) Write Control for Trigger Configuration: 0b1 = Bitfields XTMODE and XTSEL can be written

VADC->BRSMR |= (0b01 << VADC_BRSMR_ENGT_Pos) // (ENGT, bits 0-1) Enable Gate: 0b01 Conversion requests are issued if at least one pending bit is set
| (1 << VADC_BRSMR_ENTR_Pos); // (ENTR, bit 2) Enable External Trigger: 0b1 = The selected edge at the selected trigger input signal REQTR generates the load event

VADC->BRSSEL[0] = (VADC_BRSSEL_CHSELG0_Msk // (CHSELG0, bit 0) Channel Selection Group: 0b000 0001 = This channel (CH0: P2.6, Pg 24 DS) is part of the scan sequence.
| VADC_BRSSEL_CHSELG5_Msk); // (CHSELG0, bit 5) Channel Selection Group: 0b0010 0000 = This channel (CH5: P2.0, Pg 24 DS) is part of the scan sequence.

VADC->GLOBICLASS[0] |= ( (0b01111 << VADC_GLOBICLASS_STCS_Pos) // (CMS, bits 0-4) Sample Time Control for Standard Conversions: 0b11111 = 15 Additional Clock Cycles (T_Samp = 17 / f_ADC1)
| (0b000 << VADC_GLOBICLASS_CMS_Pos)); // (CMS, bits 8-10) Conversion Mode for Standard Conversions: 0b000 = 12-bit conversion

VADC->GLOBRCR &= ( ~VADC_GLOBRCR_DRCTR_Msk // Clear DRCTR Bits
& ~VADC_GLOBRCR_SRGEN_Msk); // Clear SRGEN Bits
VADC->GLOBRCR |= (0 << VADC_GLOBRCR_DRCTR_Pos) // (DRCTR, bits 16-19) Data Reduction Control: 0b0000 = Accumulate 1 result values *** THIS DOES NOT WORK!!! -- Let's discuss this..It works and I have some ideas - RJV ***
| (1 << VADC_GLOBRCR_SRGEN_Pos) // (SRGEN, bit 31) Service Request Generation Enable: 0b1 = Service request after a result event
| (1 << VADC_GLOBRCR_WFR_Pos); // (WFR, bit 24) Wait-for-Read Mode Enable: 0b1 = Wait-for-read mode enabled for this register
SHS0->GNCTR00 = ((0b0000 << SHS_GNCTR00_GAIN0_Pos) // (GAIN0, bits 0-3) Gain Control CH0 (P2.6): 0b0000 = Gain factor = 1
| (0b0000 << SHS_GNCTR00_GAIN5_Pos)); // (GAIN5, bits 20-23) Gain Control CH5 (P2.0): 0b0000 = Gain factor = 1

//Result Events are Set to C0SR1 and are active based on GLOBRCR Setup
VADC->GLOBEVNP = (0b0001 << VADC_GLOBEVNP_REV0NP_Pos); // (REV0NP, bits 16-19) Service Request Node Pointer Result Event: 0b0001 = Select shared service request line 1 of common service request group 0

NVIC_ClearPendingIRQ(VADC0_C0_1_IRQn); //Clear the Interrupt Flag
NVIC_SetPriority((IRQn_Type)VADC0_C0_1_IRQn, 0); //Set the Priority of the Interrupt
NVIC_EnableIRQ((IRQn_Type)VADC0_C0_1_IRQn); //Enable the Interrupt
}

I am anxious to rid my code of the NVIC_... XMCLib calls. When I get back to this part of the overall project, those calls will be some of the first things to go.


In your main header file:

#define P2p0_CHAN_NUM 5
#define P2p6_CHAN_NUM 0

#define MAIN_PERIPHERAL_CLOCK 64000000
#define A2D_CONVERTER_UPDATE_RATE_FREQ_Hz 10000
#define NUM_OVERSAMPLES_PER_UPDATE 4
#define A2D_CONVERTER_UPDATE_RATE_FREQ_Period (MAIN_PERIPHERAL_CLOCK / (A2D_CONVERTER_UPDATE_RATE_FREQ_Hz * NUM_OVERSAMPLES_PER_UPDATE))

void VADC0_C0_1_IRQHandler(void) __attribute__ ((section(".ram_code")));



In your main source file:

int main(void)
{
InitializeMainSystemClock();
InitializeGPIO();
PrepCCU4();
InitializeCCU4_Slice2TimerForADC(A2D_CONVERTER_UPDATE_RATE_FREQ_Period);
InitializeADC();

SCU_GENERAL->CCUCON = (1 << SCU_GENERAL_CCUCON_GSC40_Pos); // (GSC40, bit 0) Global Start Control CCU40: 0b1 = Uh,...start, I guess?
while(1)
{
}
}
void VADC0_C0_1_IRQHandler(void)
{
uviGlobRes = VADC->GLOBRES;
if ((uviGlobRes & VADC_GLOBRES_CHNR_Msk) == (P2p6_CHAN_NUM << VADC_GLOBRES_CHNR_Pos))
{
uviDALI_BusParSupplyMeasurement = (uviGlobRes & VADC_GLOBRES_RESULT_Msk); // Save the result.
}
else if ((VADC->GLOBRES & VADC_GLOBRES_CHNR_Msk) == (P2p0_CHAN_NUM << VADC_GLOBRES_CHNR_Pos))
{
uviBoostConverterMeasurement += (uviGlobRes & VADC_GLOBRES_RESULT_Msk); // Save the result.
}
}


I sincerely hope this code helps. It is *based* on some code I found in this forum a few months ago. With the help of a Infineon engineer, I was able to fine tune it and clean up the formatting to the point I could use it the way I need to. These XMC1000 processors are thoroughbred power supply processors, but only if we can tame the ADC, especially the 'one off' watered down VADC of the XMC1100.

Steve.
0 Likes