I am trying to setup the I2S Peripheral to interact with the Pmod I2S module. The FW and SCLK are not generating, however I can see the MCLK on the oscilloscope.
Using the ST32H753ZI
What I have done so far are the following:
- Setup the SPI1/I2S Clock
- Enable the GPIOA, GPIOC, DMA1, and SPI1 Clocks
- Let SP1 use the PLL2 Clock
- Setup GIPO A and C for alternative functions for A5F (PA4, PA5, PA6, PA7, PC4)
- Setup DMAMUX1
- Setup DMA1 Stream0/1 for Tx and Rx
- Setup SPI
I tried using the HAL driver and that got the FW and SCLK showing on the oscilloscope. Comparing the bare metal code and the HAL code I cant find the difference between them as the registers are all setup the same.
Any ideas what's causing the FW and SCLK not to show?
Code:
void init_I2S(){
//Setting Clock for 98.304MHz
//N = 122
//P = 8
//M = 10
//FRACT = 7209
// RCC_PLL2DIVR
// MASKING:
RCC -> PLL2DIVR &= ~RCC_PLL2DIVR_P2;
RCC -> PLL2DIVR &= ~RCC_PLL2DIVR_N2;
// WRITING:
RCC -> PLL2DIVR |= RCC_PLL2DIVR_P2_DIV8;
RCC -> PLL2DIVR |= RCC_PLL2DIVR_N2_MULT122;
// RCC_PLLCKSELR
// MASKING:
RCC -> PLLCKSELR &= ~RCC_PLLCKSELR_DIVM2;
// WRITING:
RCC -> PLLCKSELR |= RCC_PLLCKSELR_DIVM2_DIV10;
// RCC_PLL2FRACR
// MASKING:
RCC -> PLL2FRACR &= ~RCC_PLL2FRACR_FRACN2;
// WRITING:
RCC -> PLL2FRACR |= RCC_PLL2FRACR_FRACN_7209;
// 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;
// SETTING UP DMA FOR I2S
// DMAMUX1_Channel0_CCR
// DMAMUX1_Channel1_CCR
// NOTE: Using DMAMUX1 -> DMA1_Channel 0 & 1
// 0x25 = Rx | 0x26 = Tx
// MASKING:
DMAMUX1_Channel0 -> CCR &= ~DMAMUX_CxCR_DMAREQ_ID;
DMAMUX1_Channel1 -> CCR &= ~DMAMUX_CxCR_DMAREQ_ID;
// WRITING:
DMAMUX1_Channel0 -> CCR |= 0x25; //Rx
DMAMUX1_Channel1 -> CCR |= 0x26; //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 = 0x08;
DMA1_Stream1 -> NDTR = 0x08;
// DMA_SxPAR
// WRITING:
DMA1_Stream0 -> PAR = (uint32_t)&SPI1->TXDR;
DMA1_Stream1 -> PAR = (uint32_t)&SPI1->RXDR;
// DMA_SxM0AR
// WRITING:
DMA1_Stream0 -> M0AR = (uint32_t)RxBuff;
DMA1_Stream1 -> M0AR = (uint32_t)TxBuff;
// 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_DATFMT_RAlign;
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_I2SCFG_MASTER_TRANSMIT;
SPI1 -> I2SCFGR |= SPI_I2SCFGR_I2SMOD_I2S_PCM_MODE;
SPI1 -> CFG1 |= SPI_CFG1_RXDMAEN;
SPI1 -> CFG1 |= SPI_CFG1_TXDMAEN;
SPI1 -> CFG1 |= SPI_CFG1_FTHLV_2_Data;
SPI1 -> SR = 0x00;
SPI1 -> CR1 |= SPI_CR1_SPE;
SPI1 -> CR1 |= SPI_CR1_CSTART;
}