2020-10-07 07:53 PM
Hi guys,
I am having the hardest of times trying to get this to work. The only thing I got working is seeing the MCLK which shows a more of a sinewave then a PWM (is that right even)?
I tried everything, to copying the HAL code as well. When using HAL I can see my FW CLCK and SCLK, but I cant find how the HAL code is getting it to work.
Also tried using the example in the reference menu and nothing
What I have done so far procedurally is:
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;
}
2020-10-10 01:26 AM
Try polled implementation first.
Read our and check the relevant registers content, including status registers.
For DMA, make sure the used memories are fit for DMA. The H7 is overly complex.
JW
2020-10-10 10:09 AM
So I got the FWS and MCLK and SCLK outputting, it looks like now the RXDR doest want to fill up and theres no DMA request nor transfers.
2020-10-11 03:14 PM
> it looks like now the RXDR doest want to fill up
> SPI1 -> I2SCFGR |= SPI_I2SCFGR_I2SCFG_MASTER_TRANSMIT;
That sounds much like you've set it to transmit-only, i.e. no receive.
JW
2020-10-11 11:04 PM
Oh? Thats really interesting, so I guess what I am looking for is a full duplex then (both receive and transmit). Will confirm soon
2020-10-12 09:59 AM
Thank you that did it. RxBuff is now filling up. So weird HAL only allows Receive or Transmit but not duplex