2021-06-03 04:57 PM
Hi guys! I am having the biggest issue with the I2S right now
What is happening: For whatever reason the I2S does not want to transmit any samples VIA DMA. Doesnt matter what I do what I try.
The weird thing happening: The I2S WS, SCLK wont work. Only if the DMA associated with the Tx part is enable (DMA1_Stream1) which I find so weird. All it does it set the WS pin to HIGH
What I have tried:
How the code works.
The code waits around till an UART signal is received VIA the DMA, once received in goes into a super loop where it process UART signals
Depending on what UART signal was received it will enable not only the I2S peripheral but setup the clock, Interrupt, anything to make the I2S running with DMA etc...
Then the stm32 should now be ready to take in I2S signals and spit them out
Code: (Using PasteBin as code is too long here)
Main.c
I2S_Factory.c (Setups GPIO, and DMA)
Audio_Selector.c (Setups the I2S Clock, interrupt, and DMA)
DSP_FACTORY.c (Where in takes in the Rx Samples and transfer it to the Tx Buffer for transitmission)
Any help would be amazing, I am stumped right now its not even funny.
2021-06-04 09:54 AM
0x00000000240004ac is in the AXI SRAM.
0x0000000008000f60 is in FLASH, but that's just code, not a buffer.
Why do you think those are in ITCM?
2021-06-04 09:57 AM
Oh cause of this, weird
2021-06-04 09:58 AM
Right I see my mistake now correct its in the D1 Domain, what else could it be then
2021-06-04 12:33 PM
Alright @TDK I broke down the I2S module and now I am having issue just even getting the I2S working. All is happening the WS pin get set HIGH
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* <h2><center>© Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include <stdint.h>
int RxBuff_inline[4];
int TxBuff_inline[4];
uint8_t I2S1_TC = 0;
uint8_t I2S1_HC = 0;
void INIT_DMA(void);
void INIT_DMA() {
//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_DIV8; // 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;
// GPIOC -> OSPEEDR &= ~GPIO_OSPEEDR_OSPEED4;
//GPIOC -> OSPEEDR |= GPIO_OSPEEDR_OSPEED4_VERY_HIGH;
//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:
// DMA_SxCR
// WRITING:
// DMA1_Stream0 -> CR |= DMA_SxCR_EN;
//DMA1_Stream1 -> CR |= DMA_SxCR_EN;
// Setting up the SPI/I2S Peripheral
// MASKING:
SPI1->I2SCFGR = 0x00;
SPI1->I2SCFGR |= (SPI_I2SCFGR_MCKOE) |
(SPI_I2SCFGR_I2SDIV_2) |
(SPI_I2SCFGR_I2SSTD_I2STAND) |
(SPI_I2SCFGR_DATFMT_LAlign) |
(SPI_I2SCFGR_I2SCFG_MASTER_FULLDUPLEX) |
(SPI_I2SCFGR_I2SMOD_I2S_PCM_MODE);
SPI1->I2SCFGR |= (SPI_I2SCFGR_CHNEL_32BIT_WIDE);
SPI1->I2SCFGR |= (SPI_I2SCFGR_DATALEN_24BIT);
SPI1->CR1 |= SPI_CR1_SPE;
SPI1->CR1 |= SPI_CR1_CSTART;
NVIC_EnableIRQ(DMA1_Stream0_IRQn);
NVIC_SetPriority(DMA1_Stream0_IRQn,0);
}
int main (void) {
INIT_DMA();
while (1) {
if (I2S1_HC) {
for (int i = 0; i < 2; i ++){
TxBuff_inline[i] = (int)RxBuff_inline[i];
}
//DMA1_Stream1->CR |= DMA_SxCR_EN;
I2S1_HC = 0;
}
if (I2S1_TC) {
for (int i = 2; i < 4; i ++){
TxBuff_inline[i] = RxBuff_inline[i];
}
//DMA1_Stream1->CR |= DMA_SxCR_EN;
I2S1_TC = 0;
}
}
}
void DMA1_Stream0_IRQHandler() {
if (((DMA1->LISR) & (DMA_LISR_HTIF0)) != 0) {
DMA1->LIFCR |= DMA_LIFCR_CHTIF0;
I2S1_HC = 1;
}
if (((DMA1->LISR) & (DMA_LISR_TCIF0)) != 0) {
DMA1->LIFCR |= DMA_LIFCR_CTCIF0;
I2S1_TC = 1;
}
}
2021-06-05 02:23 AM
Why are you using the SPI peripheral, not the much more appropriate SAI peripheral?
Here are the definitions:
GPIOA->MODER |= (GPIO_MODER_MODE4_AF) | = (0x2UL << GPIO_MODER_MODE4_Pos)
(GPIO_MODER_MODE5_AF) | = (0x2UL << GPIO_MODER_MODE5_Pos)
(GPIO_MODER_MODE6_AF) | = (0x2UL << GPIO_MODER_MODE6_Pos)
(GPIO_MODER_MODE7_AF) ; = (0x2UL << GPIO_MODER_MODE7_Pos)
And what is this? That is not even a correct C syntax...
2021-06-05 09:37 AM
Is there really a difference? between the SPI and the SAI?
https://electronics.stackexchange.com/questions/448701/whats-the-difference-between-sai-and-i2s
2021-06-05 10:48 AM
For audio usage SAI is the preferred choice. Compared to SPI it wins in all aspects simultaneously:
2021-06-05 10:54 AM
I mean you aint wrong and ill probably do it if I can get this working. Further more I still dont know why the MOSI line is still silent.
2021-06-05 10:59 AM
@TDK Alright did what you have said.
2021-06-05 01:14 PM
> I broke down the I2S module and now I am having issue just even getting the I2S working
You don't enable the DMA clock or set up DMA1_Stream0 anywhere in there.
You don't enable the RXDMAEN or TXDMAEN bits anywhere.
Possibly other things.
Do you have it up and running without using DMA? That would be a smart first step IMO.