2020-11-30 04:33 PM
Hi everyone,
I am having the biggest of issues when it comes to getting the MCLK on the STM32 working with a FWS = 192kHz.
I followed the Clock generator cheat sheet in the reference manual and still not working.
The SCLK and FWS are working perfectly as I can measure it with an oscilloscope, but when it comes to the MCLK the signal is so faint which is where I presume the issue is coming from.
I have tried other FWS modes such as 96kHz and it works perfectly, even the MCLK signal is most more noticeable to be seen on the oscilloscope.
What's going on? The only difference in master mode from 96kHz to 192kHz is just "DIVP" 8 to a 4. So I dont know whats causing such issues.
CODE:
void init_I2S_Inline(int * RxBuff_inline, int * TxBuff_inline){
//Setting Clock for 192kHz
//N = 122
//P = 4
//M = 10
//FRACT = 7209
// RCC_PLL2DIVR
// MASKING:
RCC -> PLL2DIVR &= ~RCC_PLL2DIVR_P2;
RCC -> PLL2DIVR &= ~RCC_PLL2DIVR_N2;
// WRITING:
RCC -> PLL2DIVR |= RCC_PLL2DIVR_P2_DIV4; // P
RCC -> PLL2DIVR |= RCC_PLL2DIVR_N2_MULT122; // N
// RCC_PLLCKSELR
// MASKING:
RCC -> PLLCKSELR &= ~RCC_PLLCKSELR_DIVM2;
// WRITING:
RCC -> PLLCKSELR |= RCC_PLLCKSELR_DIVM2_DIV10; // M
// RCC_PLL2FRACR
// MASKING:
RCC -> PLL2FRACR &= ~RCC_PLL2FRACR_FRACN2;
// WRITING:
RCC -> PLL2FRACR |= RCC_PLL2FRACR_FRACN_7209; // FRAC
// RCC_PLLCFGR
// MASKING:
RCC -> PLLCFGR &= ~RCC_PLLCFGR_DIVP2EN;
RCC -> PLLCFGR &= ~RCC_PLLCFGR_PLL2RGE;
RCC -> PLLCFGR &= ~RCC_PLLCFGR_PLL2VCOSEL;
RCC -> PLLCFGR &= ~RCC_PLLCFGR_PLL2FRACEN;
// WRITING:
RCC -> PLLCFGR |= RCC_PLLCFGR_DIVP2EN;
RCC -> PLLCFGR |= RCC_PLLCFGR_PLL2RGE_4_8;
RCC -> PLLCFGR |= RCC_PLLCFGR_PLL2VCOSEL_192_836;
RCC -> PLLCFGR |= RCC_PLLCFGR_PLL2FRACEN;
// RCC_CR
// MASKING:
RCC -> CR &= ~RCC_CR_PLL2ON;
// WRITING:
RCC -> CR |= RCC_CR_PLL2ON;
// WAITING:
while (((RCC -> CR) & (RCC_CR_PLL2RDY)) == 0){};
// ENALBING CLOCKS
// RCC_AHB4ENR
// MASKING:
RCC -> AHB4ENR &= ~ RCC_AHB4ENR_GPIOAEN;
RCC -> AHB4ENR &= ~ RCC_AHB4ENR_GPIOCEN;
// WRITING:
RCC -> AHB4ENR |= RCC_AHB4ENR_GPIOAEN;
RCC -> AHB4ENR |= RCC_AHB4ENR_GPIOCEN;
// RCC_APB2ENR
// MASKING:
RCC -> APB2ENR &= ~RCC_APB2ENR_SPI1EN;
// WRITING:
RCC -> APB2ENR |= RCC_APB2ENR_SPI1EN;
// CHANGING CLOCKS OF PERIPHERALS
// RCC_D2CCIP1R
// MASKING;
RCC -> D2CCIP1R &= ~RCC_D2CCIP1R_SPI123SEL;
// WRITING:
RCC -> D2CCIP1R |= RCC_D2CCIP1R_SPI123SEL_PLL2_P_CK;
// CHANGING GPIO PINS TO ALETERNATIVE
// GPIOx_MODER
// MASKING
GPIOA -> MODER &= ~GPIO_MODER_MODE4;
GPIOA -> MODER &= ~GPIO_MODER_MODE5;
GPIOA -> MODER &= ~GPIO_MODER_MODE6;
GPIOA -> MODER &= ~GPIO_MODER_MODE7;
GPIOC -> MODER &= ~GPIO_MODER_MODE4;
// WRITING:
GPIOA -> MODER |= GPIO_MODER_MODE4_ALT;
GPIOA -> MODER |= GPIO_MODER_MODE5_ALT;
GPIOA -> MODER |= GPIO_MODER_MODE6_ALT;
GPIOA -> MODER |= GPIO_MODER_MODE7_ALT;
GPIOC -> MODER |= GPIO_MODER_MODE4_ALT;
//SETTING ALT FUNCTIONS TO PINS
// GPIOx_AFRL
// MASKING:
GPIOA -> AFR[0] &= ~GPIO_AFRL_AFSEL4;
GPIOA -> AFR[0] &= ~GPIO_AFRL_AFSEL5;
GPIOA -> AFR[0] &= ~GPIO_AFRL_AFSEL6;
GPIOA -> AFR[0] &= ~GPIO_AFRL_AFSEL7;
GPIOC -> AFR[0] &= ~GPIO_AFRL_AFSEL4;
// WRITING;
GPIOA -> AFR[0] |= GPIO_AFRL_AFSEL4_AF5;
GPIOA -> AFR[0] |= GPIO_AFRL_AFSEL5_AF5;
GPIOA -> AFR[0] |= GPIO_AFRL_AFSEL6_AF5;
GPIOA -> AFR[0] |= GPIO_AFRL_AFSEL7_AF5;
GPIOC -> AFR[0] |= GPIO_AFRL_AFSEL4_AF5;
// ENABLING DMA1
// RCC_AHB1ENR
// MASKING:
RCC -> AHB1ENR &= ~RCC_AHB1ENR_DMA1EN;
// WRITING:
RCC -> AHB1ENR |= RCC_AHB1ENR_DMA1EN;
// MASKING:
DMAMUX1_Channel0 -> CCR &= ~DMAMUX_CxCR_DMAREQ_ID;
DMAMUX1_Channel1 -> CCR &= ~DMAMUX_CxCR_DMAREQ_ID;
// WRITING:
DMAMUX1_Channel0 -> CCR |= DMAMUX_CxCR_DMAREQ_ID_SPI1_Rx; //Rx
DMAMUX1_Channel1 -> CCR |= DMAMUX_CxCR_DMAREQ_ID_SPI1_Tx; //Tx
// DMA1_Stream0_CR
// DMA1_Stream1_CR
// MASKING:
DMA1_Stream0 -> CR &= ~DMA_SxCR_CT;
DMA1_Stream0 -> CR &= ~DMA_SxCR_PL;
DMA1_Stream0 -> CR &= ~DMA_SxCR_MSIZE;
DMA1_Stream0 -> CR &= ~DMA_SxCR_PSIZE;
DMA1_Stream0 -> CR &= ~DMA_SxCR_MINC;
DMA1_Stream0 -> CR &= ~DMA_SxCR_CIRC;
DMA1_Stream0 -> CR &= ~DMA_SxCR_DIR;
DMA1_Stream0 -> CR &= ~DMA_SxCR_PFCTRL;
DMA1_Stream0 -> CR &= ~DMA_SxCR_TCIE;
DMA1_Stream0 -> CR &= ~DMA_SxCR_HTIE;
DMA1_Stream1 -> CR &= ~DMA_SxCR_CT;
DMA1_Stream1 -> CR &= ~DMA_SxCR_PL;
DMA1_Stream1 -> CR &= ~DMA_SxCR_MSIZE;
DMA1_Stream1 -> CR &= ~DMA_SxCR_PSIZE;
DMA1_Stream1 -> CR &= ~DMA_SxCR_MINC;
DMA1_Stream1 -> CR &= ~DMA_SxCR_CIRC;
DMA1_Stream1 -> CR &= ~DMA_SxCR_DIR;
DMA1_Stream1 -> CR &= ~DMA_SxCR_PFCTRL;
// WRITING:
DMA1_Stream0 -> CR |= DMA_SxCR_CT_MEM0;
DMA1_Stream0 -> CR |= DMA_SxCR_PL_Very_High;
DMA1_Stream0 -> CR |= DMA_SxCR_MSIZE_32BIT;
DMA1_Stream0 -> CR |= DMA_SxCR_PSIZE_32BIT;
DMA1_Stream0 -> CR |= DMA_SxCR_MINC;
DMA1_Stream0 -> CR |= DMA_SxCR_CIRC;
DMA1_Stream0 -> CR |= DMA_SxCR_DIR_P_TO_M;
DMA1_Stream0 -> CR |= DMA_SxCR_PFCTRL_DMAFLOW;
DMA1_Stream0 -> CR |= DMA_SxCR_TCIE;
DMA1_Stream0 -> CR |= DMA_SxCR_HTIE;
DMA1_Stream1 -> CR |= DMA_SxCR_CT_MEM0;
DMA1_Stream1 -> CR |= DMA_SxCR_PL_Very_High;
DMA1_Stream1 -> CR |= DMA_SxCR_MSIZE_32BIT;
DMA1_Stream1 -> CR |= DMA_SxCR_PSIZE_32BIT;
DMA1_Stream1 -> CR |= DMA_SxCR_MINC;
DMA1_Stream1 -> CR |= DMA_SxCR_CIRC;
DMA1_Stream1 -> CR |= DMA_SxCR_DIR_M_TO_P;
DMA1_Stream1 -> CR |= DMA_SxCR_PFCTRL_DMAFLOW;
// DMA_SxNDTR
// WRITING:
DMA1_Stream0 -> NDTR = 0x4;
DMA1_Stream1 -> NDTR = 0x4;
// DMA_SxPAR
// WRITING:
DMA1_Stream0 -> PAR = (int) & SPI1 -> RXDR;
DMA1_Stream1 -> PAR = (int) & SPI1 -> TXDR;
// DMA_SxM0AR
// WRITING:
DMA1_Stream0 -> M0AR = (int) RxBuff_inline;
DMA1_Stream1 -> M0AR = (int) TxBuff_inline;
// DMA_SxCR
// WRITING:
DMA1_Stream0 -> CR |= DMA_SxCR_EN;
DMA1_Stream1 -> CR |= DMA_SxCR_EN;
// Setting up the SPI/I2S Peripheral
// MASKING:
SPI1 -> I2SCFGR &= ~SPI_I2SCFGR_MCKOE;
SPI1 -> I2SCFGR &= ~SPI_I2SCFGR_ODD;
SPI1 -> I2SCFGR &= ~SPI_I2SCFGR_I2SDIV;
SPI1 -> I2SCFGR &= ~SPI_I2SCFGR_DATFMT;
SPI1 -> I2SCFGR &= ~SPI_I2SCFGR_WSINV;
SPI1 -> I2SCFGR &= ~SPI_I2SCFGR_DATLEN;
SPI1 -> I2SCFGR &= ~SPI_I2SCFGR_CHLEN;
SPI1 -> I2SCFGR &= ~SPI_I2SCFGR_CKPOL;
SPI1 -> I2SCFGR &= ~SPI_I2SCFGR_I2SSTD;
SPI1 -> I2SCFGR &= ~SPI_I2SCFGR_I2SCFG;
SPI1 -> I2SCFGR &= ~SPI_I2SCFGR_I2SMOD;
SPI1 -> CFG1 &= ~SPI_CFG1_RXDMAEN;
SPI1 -> CFG1 &= ~SPI_CFG1_TXDMAEN;
SPI1 -> CFG1 &= ~SPI_CFG1_FTHLV;
// WRITING:
SPI1 -> I2SCFGR |= SPI_I2SCFGR_MCKOE;
SPI1 -> I2SCFGR |= SPI_I2SCFGR_ODD_MULT2;
SPI1 -> I2SCFGR |= SPI_I2SCFGR_I2SDIV_2;
SPI1 -> I2SCFGR |= SPI_I2SCFGR_WSINV_I2S;
SPI1 -> I2SCFGR |= SPI_I2SCFGR_DATALEN_24BIT;
SPI1 -> I2SCFGR |= SPI_I2SCFGR_CKPOL_FALL_RISE;
SPI1 -> I2SCFGR |= SPI_I2SCFGR_I2SSTD_I2STAND;
SPI1 -> I2SCFGR |= SPI_I2SCFGR_CHNEL_32BIT_WIDE;
SPI1 -> I2SCFGR |= SPI_I2SCFGR_I2SCFG_MASTER_FULLDUPLEX;
SPI1 -> I2SCFGR |= SPI_I2SCFGR_I2SMOD_I2S_PCM_MODE;
SPI1 -> I2SCFGR |= SPI_I2SCFGR_DATFMT_LAlign;
//SPI1 -> I2SCFGR |= SPI_CFG1_FTHLV_2_Data;
SPI1 -> CFG1 |= SPI_CFG1_RXDMAEN;
SPI1 -> CFG1 |= SPI_CFG1_TXDMAEN;
/*SPI1 -> CR1 |= SPI_CR1_SPE;
SPI1 -> CR1 |= SPI_CR1_CSTART;*/
}
Solved! Go to Solution.
2020-12-01 08:39 AM
I think i figured it out, the ADC/DAC device I am using doesn't support 192kHz. But thank you for getting my MCLK visible
2020-11-30 10:31 PM
> MCLK the signal is so faint
How is GPIO_OSPEEDR set for that signal?
Do you have an adequate oscilliscope probe for high-frequency signals?
JW
2020-11-30 10:43 PM
Those are some good suggestion, as of right now
GPIO_OSPEEDR for PC4 (MCLK) is set as 0x00 (low speed)
The scope probe is good for 200MHz
2020-12-01 01:01 AM
> GPIO_OSPEEDR for PC4 (MCLK) is set as 0x00 (low speed)
Okay so set it higher.
JW
2020-12-01 08:07 AM
Yup, set it higher. I can see the MCLK clearly now, however audio is not playing still. The weird part when I prob the MCLK line with the oscilloscope I can hear the music but distorted. For the record I set the PC4 (MLCK) pin to be (very high speed)
2020-12-01 08:12 AM
Measured the MCLK line at FWS = 96kHz and the Vp-p is ~1.7V whereas the MCLK line at FWS = 192kHz = 700mV could that be the issue?
2020-12-01 08:39 AM
I think i figured it out, the ADC/DAC device I am using doesn't support 192kHz. But thank you for getting my MCLK visible