DSD without Hardware Trigger from other peripheral

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

cross mob
Not applicable
Hi!

I want to set up the Delta Sigma demodulator to use it with an Avago ACPL 796. Here the clock is generated by the XMC4400 and the ACPL sends back the data stream.
I tried to set it up like I thought it is necessary but in the Result Register (RESMx) there only occur the values 0x0000 or 0x0001 or 0xffff.
Why are there only this 3 values??
The register DSD.EVFLAG says: "A new result has been stored in register RESMx (1)" for this channel.
How can I set up an Interrupt when a new result is stored in this register?


int32_t DSD_init(void)
{

// Apply reset on DSD
SCU_RESET->PRSET0 = SCU_RESET_PRSET0_DSDRS_Msk;

// De-assert reset on DSD
SCU_RESET->PRCLR0 = SCU_RESET_PRCLR0_DSDRS_Msk;

// activated the DSD modul clock by resetting bit 1
DSD->CLC &= (uint32_t)(~((uint32_t)0x01U));

/* Set divder factor for modulator clock ( 0x03UL = fCLK/8 ? = 15MHz)
0H fMOD = fCLK / 2
1H fMOD = fCLK / 4
2H fMOD = fCLK / 6
...
FH fMOD = fCLK / 32
*/
DSD_CH0->MODCFG |= (( 0x03UL << DSD_CH_MODCFG_DIVM_Pos ) & DSD_CH_MODCFG_DIVM_Msk) |
// Enable write access to MODCFG.DIVM
(( 0x01UL << DSD_CH_MODCFG_DWC_Pos ) & DSD_CH_MODCFG_DWC_Msk);
DSD_CH1->MODCFG |= (( 0x03UL << DSD_CH_MODCFG_DIVM_Pos ) & DSD_CH_MODCFG_DIVM_Msk)|
(( 0x01UL << DSD_CH_MODCFG_DWC_Pos ) & DSD_CH_MODCFG_DWC_Msk);
//DSD_CH2->MODCFG |= (( 0x03UL << DSD_CH_MODCFG_DIVM_Pos ) & DSD_CH_MODCFG_DIVM_Msk)|
// (( 0x01UL << DSD_CH_MODCFG_DWC_Pos ) & DSD_CH_MODCFG_DWC_Msk);
DSD_CH3->MODCFG |= (( 0x03UL << DSD_CH_MODCFG_DIVM_Pos ) & DSD_CH_MODCFG_DIVM_Msk)|
(( 0x01UL << DSD_CH_MODCFG_DWC_Pos ) & DSD_CH_MODCFG_DWC_Msk);

DSD_CH1->DICFG = 0x00000000;

//Input channel select
//use B non inverted input for all channels
DSD_CH0->DICFG |= (( 0x04UL << DSD_CH_DICFG_DSRC_Pos ) & DSD_CH_DICFG_DSRC_Msk)| // B direct
// Enable write acces to DICFG.DSRC
(( 0x01UL << DSD_CH_DICFG_DSWC_Pos ) & DSD_CH_DICFG_DSWC_Msk);
DSD_CH1->DICFG |= (( 0x04UL << DSD_CH_DICFG_DSRC_Pos ) & DSD_CH_DICFG_DSRC_Msk)|// B direct
(( 0x01UL << DSD_CH_DICFG_DSWC_Pos ) & DSD_CH_DICFG_DSWC_Msk);
//DSD_CH2->DICFG |= (( 0x04UL << DSD_CH_DICFG_DSRC_Pos ) & DSD_CH_DICFG_DSRC_Msk)|// B direct
// (( 0x01UL << DSD_CH_DICFG_DSWC_Pos ) & DSD_CH_DICFG_DSWC_Msk);
DSD_CH3->DICFG |= (( 0x04UL << DSD_CH_DICFG_DSRC_Pos ) & DSD_CH_DICFG_DSRC_Msk)|// B direct
(( 0x01UL << DSD_CH_DICFG_DSWC_Pos ) & DSD_CH_DICFG_DSWC_Msk);


//Integrator trigger mode set to active all the time
DSD_CH0->DICFG |= (( 0x03UL << DSD_CH_DICFG_ITRMODE_Pos ) & DSD_CH_DICFG_ITRMODE_Msk)|
// Enable write acces to DICFG.TSTRMODE / TRSEL ITRMODE
(( 0x01UL << DSD_CH_DICFG_TRWC_Pos ) & DSD_CH_DICFG_TRWC_Msk);
DSD_CH1->DICFG |= (( 0x03UL << DSD_CH_DICFG_ITRMODE_Pos ) & DSD_CH_DICFG_ITRMODE_Msk)|
(( 0x01UL << DSD_CH_DICFG_TRWC_Pos ) & DSD_CH_DICFG_TRWC_Msk);
//DSD_CH2->DICFG |= (( 0x02UL << DSD_CH_DICFG_ITRMODE_Pos ) & DSD_CH_DICFG_ITRMODE_Msk)|
// (( 0x01UL << DSD_CH_DICFG_TRWC_Pos ) & DSD_CH_DICFG_TRWC_Msk);
DSD_CH3->DICFG |= (( 0x03UL << DSD_CH_DICFG_ITRMODE_Pos ) & DSD_CH_DICFG_ITRMODE_Msk)|
(( 0x01UL << DSD_CH_DICFG_TRWC_Pos ) & DSD_CH_DICFG_TRWC_Msk);


//Data strobe
//direct clock, a sample trigger is generated at each rising clock edge
DSD_CH0->DICFG |= (( 0x02UL << DSD_CH_DICFG_STROBE_Pos ) & DSD_CH_DICFG_STROBE_Msk)|
// Enable write access to DICFG.TSTRMODE / TRSEL ITRMODE
(( 0x01UL << DSD_CH_DICFG_SCWC_Pos ) & DSD_CH_DICFG_SCWC_Msk);
DSD_CH1->DICFG |= (( 0x02UL << DSD_CH_DICFG_STROBE_Pos ) & DSD_CH_DICFG_STROBE_Msk)|
(( 0x01UL << DSD_CH_DICFG_SCWC_Pos ) & DSD_CH_DICFG_SCWC_Msk);
//DSD_CH2->DICFG |= (( 0x02UL << DSD_CH_DICFG_STROBE_Pos ) & DSD_CH_DICFG_STROBE_Msk)|
// (( 0x01UL << DSD_CH_DICFG_SCWC_Pos ) & DSD_CH_DICFG_SCWC_Msk);
DSD_CH3->DICFG |= (( 0x02UL << DSD_CH_DICFG_STROBE_Pos ) & DSD_CH_DICFG_STROBE_Msk)|
(( 0x01UL << DSD_CH_DICFG_SCWC_Pos ) & DSD_CH_DICFG_SCWC_Msk);



//Sample clock source select is set to internal clock
DSD_CH0->DICFG |= (( 0x0FUL << DSD_CH_DICFG_CSRC_Pos ) & DSD_CH_DICFG_CSRC_Msk)|
// Enable write acces to DICFG.STROBE, CSRC
(( 0x01UL << DSD_CH_DICFG_SCWC_Pos ) & DSD_CH_DICFG_SCWC_Msk);
DSD_CH1->DICFG |= (( 0x0FUL << DSD_CH_DICFG_CSRC_Pos ) & DSD_CH_DICFG_CSRC_Msk)|
(( 0x01UL << DSD_CH_DICFG_SCWC_Pos ) & DSD_CH_DICFG_SCWC_Msk);
//DSD_CH2->DICFG |= (( 0x0FUL << DSD_CH_DICFG_CSRC_Pos ) & DSD_CH_DICFG_CSRC_Msk)|
// (( 0x01UL << DSD_CH_DICFG_SCWC_Pos ) & DSD_CH_DICFG_SCWC_Msk);
DSD_CH3->DICFG |= (( 0x0FUL << DSD_CH_DICFG_CSRC_Pos ) & DSD_CH_DICFG_CSRC_Msk)|
(( 0x01UL << DSD_CH_DICFG_SCWC_Pos ) & DSD_CH_DICFG_SCWC_Msk);



/* Select Modul clock
* 000B Internal clock off, no source selected
* 001B fDSD
*/
DSD->GLOBCFG |= (( 0x01UL << DSD_GLOBCFG_MCSEL_Pos) & DSD_GLOBCFG_MCSEL_Msk);

//Run all DSD
DSD->GLOBRC |= 0x0BUL ; // Bit 0-3 = 1011 -> run ch0 ch1 ch3

// Config GPIO
// Config Clock ch0 out on P4.1 to Push-Pull Alternate function 3
// PORT4->IOCR0 |= (( 0x13UL << PORT4_IOCR0_PC1_Pos ) & PORT4_IOCR0_PC1_Msk );
// Config Clock ch1 out on P4.0 to Push-Pull Alternate function 3
PORT4->IOCR0 |= (( 0x13UL << PORT4_IOCR0_PC0_Pos ) & PORT4_IOCR0_PC0_Msk );
// Config Clock ch3 out on P3.4 to Push-Pull Alternate function 4
// PORT3->IOCR4 |= (( 0x14UL << PORT3_IOCR4_PC4_Pos ) & PORT3_IOCR4_PC4_Msk );




return 0;
}


Thanks for any answer.

Benedikt
0 Likes
4 Replies
Eric1
Employee
Employee
Hallo Benedikt,

It looks you are already familiar with DSD.

Still I would recommend to use the DSDIF003 App or if you want to do a Resolver specific Application the DSDRV App.

Service Request:
With "Signal connection" (right click on the App) you can directly connect the Result interrupt to a NVIC002 App.
Here you enter your function name you want to call and activate the interrupt.
Now for each new result your function is called.

Additionally:

1) Did you check if Data output frequency is the same as Clock input frequency?
2) Did you check the Clock and the Bitstream on oscilloscope?

3) You activate the Integrator without configuring the IWCTRx register. Do you want to use the integrator? For current sensing this is not mandatory.
4) Your comment says Strobe = rising edge, configuration is falling edge.

5) FCFGC configuration is missing. I would recommend CFMDF=63, CFMC=2, CFEN=1, SRGM=3, CFMSV=3,

Regards
Eric
0 Likes
Eric1
Employee
Employee
May this helps also:

Port configuration is missing...



/*
* // Example with interrupt:
*
* #define interrupt_DSD_CH2 DSD0_2_IRQHandler
*
* DSD_FILTER_INIT_t filter_1 = {
* .filter_type = DSD_FILTER_TYPE_COMB3 = 2,
* .decimation_factor = 64U,
* .start_value = 4U,
* .data_source = DSD_FILTER_DATA_SOURCE_A_DIRECT =2 ,
* .clock_source= DSD_FILTER_CLOCK_SOURCE_INTERN= 15,
* .strobe=DSD_STROBE_DOUBLE_CLOCK_RISE = 5,
* .clock_divider = DSD_FILTER_CLK_DIV_6 = 2,
* .offset = 0,
* .result_sr= DSD_SERVICE_REQUEST_YES =1,
* } ;
*
* DSD_Enable_Module();
* DSD_Filter_Init(DSD_CH2, &filter_1);
* DSD_Enable_Channel(DSD_ENABLE_CH2);
* NVIC_EnableIRQ(DSD0_M_2_IRQn);
*
* while(1)
* {
*
* }
* return 0;
* }
*
* void interrupt_DSD_CH2 (void)
* {
* // your code
* }
*/

uint8_t DSD_Enable_Module(void)
{
SCU_RESET->PRCLR0 |= SCU_RESET_PRCLR0_DSDRS_Msk; // Deadress DSD
DSD->CLC &= ~DSD_CLC_DISR_Msk; // On Request: enable the module clock
DSD->GLOBCFG = 0x01; // DSD_GLOBCFG_MCSEL select fdsd as clock (Fdsd = Fpb)
return DSD_STATUS_OK;
}

uint8_t DSD_Filter_Init(DSD_CH_TypeDef* Channel_number,DSD_FILTER_INIT_t* init)
{

/*Subtract decimation_factor for calculation transformed back at end of function*/
init->decimation_factor--;

/*Check boundaries*/
if(init->start_value<4)
return DSD_STATUS_WRONG_INPUT;
if(init->decimation_factor<=3 || init->decimation_factor>=255)
return DSD_STATUS_WRONG_INPUT;
if (init->clock_divider>DSD_FILTER_CLK_DIV_32)
return DSD_STATUS_WRONG_INPUT;


/*Set Channel frequency*/
Channel_number->MODCFG = (init->clock_divider<
/* Input Data/Clk */
Channel_number->DICFG = init->data_source |
DSD_CH_DICFG_DSWC_Msk |
(init->clock_source << DSD_CH_DICFG_CSRC_Pos) |
(init->strobe << DSD_CH_DICFG_STROBE_Pos) |
DSD_CH_DICFG_SCWC_Msk;

/* Filter setup*/
Channel_number->FCFGC = (init->decimation_factor) |
(init->filter_type << DSD_CH_FCFGC_CFMC_Pos) |
DSD_CH_FCFGC_CFEN_Msk |
(init->start_value << DSD_CH_FCFGC_CFMSV_Pos);
/* Offset */
Channel_number->OFFM = init->offset;

/*Back transformation of decimation_factor for better code visibility*/
init->decimation_factor++;

/* Service Request */
if(init->result_sr)
Channel_number->FCFGC |= DSD_CH_FCFGC_SRGM_Msk;
else
Channel_number->FCFGC &= ~DSD_CH_FCFGC_SRGM_Msk;

return DSD_STATUS_OK;
}

uint8_t DSD_Enable_Channel(DSD_ENABLE_CH_t Enable)
{
DSD->GLOBRC|= Enable;
return DSD_STATUS_OK;
}
0 Likes
Not applicable
Thanks for your answer. Now the DSD works.
Now I want to use the auxiliary filter to build an overcurrent protection.
How would you configure the auxiliary filter?
I think CIC1 and what decimation factor?

Thanks for answers.

Benedikt
0 Likes
Eric1
Employee
Employee
Hi Benedikt,

It depends how fast you want to react and how many resolution you need.

I think a good starting point is CIC2 or CIC3 (Depending on the Modulator)
and decimation factor 16.

e.g. CIC2, dec 16, samplefrequency 10MHz:

Response time: 3,2us
Update time: 1,6us
max out in bit with sign bit: 9
0 Likes