1
\$\begingroup\$

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:

  • Verified the registers are correctly setup
  • Ensure with measuring tools the right signals are shooting out (WS, MCLK, SCLK) when the DMA1_Stream1 is enable
  • Swapped out the ADC/DAC for another one
  • Ensured the ADC is sending out its digital signal
  • Ensured the STM32 is receiving samples and transmitting to the Tx Buffer associated with the DMA

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)

The code flow for anyone that needs to follow along

Main - > I2S_Factory -> Audio_Selector -> DSP_FACTORY

Main.c

https://pastebin.com/GZCTs8Sd

I2S_Factory.c (Setups GPIO, and DMA)

https://pastebin.com/tDXjzVaX

Audio_Selector.c (Setups the I2S Clock, interrupt, and DMA)

https://pastebin.com/mHjDgZaX

DSP_FACTORY.c (Where in takes in the Rx Samples and transfer it to the Tx Buffer for transitmission)

https://pastebin.com/WNt9TSrA

Any help would be amazing, I am stumped right now its not even funny.

Update 1: Seeing if DTCM or ITCM memory region is being used enter image description here

Update 2: Here is the MAP file and the variables that use the DMA

.bss.I2S1_TxBUFF
                0x00000000240004ac       0x10 Core/Src/driver/I2S_FACTORY.o
 .bss.I2S1_RxBUFF
                0x00000000240004bc       0x10 Core/Src/driver/I2S_FACTORY.o
 .bss.UART4_RxBUFF
                0x00000000240004cc        0x1 Core/Src/driver/UART_FACTORY.o

.text.getUART4_RxBUFF
                0x0000000008000f60       0x14 Core/Src/driver/UART_FACTORY.o
                0x0000000008000f60                getUART4_RxBUFF
    .text.getI2S1_TxBUFF
                0x0000000008000cd0       0x14 Core/Src/driver/I2S_FACTORY.o
                0x0000000008000cd0                getI2S1_TxBUFF
 .text.getI2S1_RxBUFF
                0x0000000008000ce4       0x14 Core/Src/driver/I2S_FACTORY.o
                0x0000000008000ce4                getI2S1_RxBUFF

Update 3:

What I have done so far.

  • Ensured the data used by the DMA is in the regions where the DMA can access it
  • I created the most minimal working example I can, just setting up the Clock, DMA, I2S, and interrupt thats it.
  • No errors are being reported by the DMA nor the SPI and I still see no activity on the MOSI line.
  • Doubled checked the clocks are set right, and once again the WS, SCLK, and MCLK are outputting normally, MISO is working properly
  • Tested the DAC, thats working properly
  • Lost really lost

Update 4:

Updated the code to be more simplifier and really focus on the problem.

/* USER CODE BEGIN Header */
/**
 ******************************************************************************
 * @file           : main.c
 * @brief          : Main program body
 ******************************************************************************
 * @attention
 *
 * <h2><center>&copy; 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 I2S1_TxBUFF[4];
 int I2S1_RxBUFF[4];

uint8_t I2S1_TC = 0;
uint8_t I2S1_HC = 0;

void INIT_DMA(void);
void INIT_CLOCK(void);
void INIT_GPIO(void);
void INIT_I2S(void);
void INIT_INTERRUPT(void);

void INIT_CLOCK() {

    FLASH -> ACR &= ~((FLASH_ACR_LATENCY)   |
                         (FLASH_ACR_WRHIGHFREQ));

        FLASH -> ACR |= (FLASH_ACR_LATENCY_4WS) |
                        (FLASH_ACR_WRHIGHFREQ_2);
        RCC -> APB4ENR &= ~(RCC_APB4ENR_SYSCFGEN);
            RCC -> APB4ENR |= (RCC_APB4ENR_SYSCFGEN);

            PWR -> D3CR &= ~(PWR_D3CR_VOS);
            PWR -> D3CR |= PWR_D3CR_VOS_SCALE1;

            PWR ->CR3 &= ~(PWR_CR3_LDOEN);
            PWR ->CR3 |= (PWR_CR3_LDOEN);

            SYSCFG -> PWRCR |= (SYSCFG_PWRCR_ODEN);

            while (!((PWR -> D3CR) & (PWR_D3CR_VOSRDY)));

            RCC -> PLLCKSELR &= ~(RCC_PLLCKSELR_DIVM1);
                RCC -> PLLCKSELR |= (RCC_PLLCKSELR_DIVM1_DIV4);

                RCC -> PLLCFGR   &= ~(RCC_PLLCFGR_PLL1RGE);
                RCC -> PLLCFGR   |=  (RCC_PLLCFGR_PLL1RGE_8MHz_16MHz);

                RCC -> PLL1DIVR  &= ~ (RCC_PLL1DIVR_N1);
                RCC -> PLL1DIVR  |= (RCC_PLL1DIVR_N1_60);

                RCC -> D1CFGR |= (RCC_D1CFGR_HPRE_DIV2)  |
                                 (RCC_D1CFGR_D1PPRE_DIV2);

                if (((RCC->D1CFGR) & (RCC_D1CFGR_HPRE_DIV2)) != RCC_D1CFGR_HPRE_DIV2) {

                    //exit(0);
                }

                if (((RCC->D1CFGR) & (RCC_D1CFGR_D1PPRE_DIV2)) != RCC_D1CFGR_D1PPRE_DIV2) {

                    //exit(0);
                }

                RCC -> D2CFGR |= (RCC_D2CFGR_D2PPRE1_DIV2) |
                                 (RCC_D2CFGR_D2PPRE2_DIV2);

                RCC -> D3CFGR |= RCC_D3CFGR_D3PPRE_DIV2;

                RCC -> CR     |= RCC_CR_PLL1ON;

                while (!((RCC -> CR) & (RCC_CR_PLL1RDY)));

                RCC -> CFGR &= ~(RCC_CFGR_SW);
                RCC -> CFGR |= RCC_CFGR_SW_PLL1;

                if ((( RCC -> CFGR) & (RCC_CFGR_SWS)) != (RCC_CFGR_SWS_PLL1)) {

                    //exit(0);
               }
}

void INIT_GPIO() {

    // ! ---- PINS USED
    // PA4 = I2S1_WS
    // PA5 = I2S1_CK
    // PA6 = MISO
    // PA7 = MOSI
    // PC4 = MCK

    // GPIOA & C Clock
    RCC->AHB4ENR &= ~((RCC_AHB4ENR_GPIOAEN) |
                      (RCC_AHB4ENR_GPIOCEN));

    RCC->AHB4ENR |= (RCC_AHB4ENR_GPIOAEN) |
                    (RCC_AHB4ENR_GPIOCEN);


    GPIOA->MODER &= ~((GPIO_MODER_MODE4) |
                      (GPIO_MODER_MODE5) |
                      (GPIO_MODER_MODE6) |
                      (GPIO_MODER_MODE7));

    GPIOA->MODER |= (GPIO_MODER_MODE4_AF) |
                    (GPIO_MODER_MODE5_AF) |
                    (GPIO_MODER_MODE6_AF) |
                    (GPIO_MODER_MODE7_AF);

    GPIOC->MODER &= ~(GPIO_MODER_MODE4);
    GPIOC->MODER |=  (GPIO_MODER_MODE4_AF);


    GPIOA->OSPEEDR &= ~((GPIO_OSPEEDR_OSPEED4) |
                        (GPIO_OSPEEDR_OSPEED5) |
                        (GPIO_OSPEEDR_OSPEED6) |
                        (GPIO_OSPEEDR_OSPEED7));

    GPIOA->OSPEEDR |=   (GPIO_OSPEEDR_OSPEED4_VERY_HIGH_SPEED) |
                        (GPIO_OSPEEDR_OSPEED5_VERY_HIGH_SPEED) |
                        (GPIO_OSPEEDR_OSPEED6_VERY_HIGH_SPEED) |
                        (GPIO_OSPEEDR_OSPEED7_VERY_HIGH_SPEED);

    GPIOC->OSPEEDR &= ~((GPIO_OSPEEDR_OSPEED4));
    GPIOC->OSPEEDR |=   (GPIO_OSPEEDR_OSPEED4_VERY_HIGH_SPEED);

    GPIOA->AFR[0] &= ~((GPIO_AFRL_AFSEL4) |
                       (GPIO_AFRL_AFSEL5) |
                       (GPIO_AFRL_AFSEL6) |
                       (GPIO_AFRL_AFSEL7));

    GPIOA->AFR[0] |=   (GPIO_AFRL_AFSEL4_I2S1_WS)   |
                       (GPIO_AFRL_AFSEL5_I2S1_CK)   |
                       (GPIO_AFRL_AFSEL6_I2S1_MISO) |
                       (GPIO_AFRL_AFSEL7_I2S1_MOSI);

    GPIOC->AFR[0] &= ~(GPIO_AFRL_AFSEL4);
    GPIOC->AFR[0] |=  (GPIO_AFRL_AFSEL4_I2S1_MCK);
}

void INIT_DMA() {

    // ENABLE DMA
    RCC->AHB1ENR &= ~(RCC_AHB1ENR_DMA1EN);
    RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN;

    //Setup DMA
    DMAMUX1_Channel0->CCR &= ~(DMAMUX_CxCR_DMAREQ_ID);
    DMAMUX1_Channel0->CCR |=  (DMAMUX_CxCR_DMAREQ_ID_I2S1_Rx);

    DMAMUX1_Channel1->CCR &= ~(DMAMUX_CxCR_DMAREQ_ID);
    DMAMUX1_Channel1->CCR |=  (DMAMUX_CxCR_DMAREQ_ID_I2S1_Tx);

    DMA1_Stream0->CR &= ~((DMA_SxCR_CT)    |
                          (DMA_SxCR_PL)    |
                          (DMA_SxCR_MSIZE) |
                          (DMA_SxCR_PSIZE) |
                          (DMA_SxCR_MINC)  |
                          (DMA_SxCR_CIRC)  |
                          (DMA_SxCR_DIR)   |
                          (DMA_SxCR_PFCTRL)|
                          (DMA_SxCR_TCIE)  |
                          (DMA_SxCR_HTIE));

    DMA1_Stream0->CR |=   (DMA_SxCR_CT_MEM0)           |
                          (DMA_SxCR_PL_VERY_HIGH)      |
                          (DMA_SxCR_MSIZE_32BIT)       |
                          (DMA_SxCR_PSIZE_32BIT)       |
                          (DMA_SxCR_MINC)              |
                          (DMA_SxCR_CIRC)              |
                          (DMA_SxCR_DIR_PERI_TO_MEM)   |
                          (DMA_SxCR_PFCTRL_DMA_FLOW)   |
                          (DMA_SxCR_TCIE)              |
                          (DMA_SxCR_HTIE);

    DMA1_Stream1->CR &= ~((DMA_SxCR_CT)    |
                          (DMA_SxCR_PL)    |
                          (DMA_SxCR_MSIZE) |
                          (DMA_SxCR_PSIZE) |
                          (DMA_SxCR_MINC)  |
                          (DMA_SxCR_CIRC)  |
                          (DMA_SxCR_DIR)   |
                          (DMA_SxCR_PFCTRL)|
                          (DMA_SxCR_TCIE)  |
                          (DMA_SxCR_HTIE));

    DMA1_Stream1->CR |=   (DMA_SxCR_CT_MEM0)           |
                          (DMA_SxCR_PL_VERY_HIGH)      |
                          (DMA_SxCR_MSIZE_32BIT)       |
                          (DMA_SxCR_PSIZE_32BIT)       |
                          (DMA_SxCR_MINC)              |
                          (DMA_SxCR_CIRC)              |
                          (DMA_SxCR_DIR_MEM_TO_PERI)   |
                          (DMA_SxCR_PFCTRL_DMA_FLOW);

    DMA1_Stream0->NDTR = 4;
    DMA1_Stream1->NDTR = 4;

    DMA1_Stream0->PAR = (int)&SPI1->RXDR;
    DMA1_Stream0->M0AR = (int)I2S1_RxBUFF;

    DMA1_Stream1->PAR = (int)&SPI1->TXDR;
    DMA1_Stream1->M0AR = (int)I2S1_TxBUFF;

    DMA1_Stream0->CR |= DMA_SxCR_EN;
    DMA1_Stream1->CR |= DMA_SxCR_EN;

}


void INIT_I2S() {

    RCC->APB2ENR |= (RCC_APB2ENR_SPI1EN);

    RCC -> PLLCKSELR &= ~(RCC_PLLCKSELR_DIVM2);
            RCC -> PLLCKSELR |=  (RCC_PLLCKSELR_DIVM2_DIV10);

            RCC -> PLL2FRACR = 0;
            RCC -> PLL2FRACR = (RCC_PLL2FRACR_FRACN2_7209);

            RCC -> PLLCFGR   &= ~((RCC_PLLCFGR_PLL2VCOSEL) |
                                  (RCC_PLLCFGR_PLL2RGE)    |
                                  (RCC_PLLCFGR_PLL2FRACEN) |
                                  (RCC_PLLCFGR_DIVP2EN)    |
                                  (RCC_PLLCFGR_DIVQ2EN)    |
                                  (RCC_PLLCFGR_DIVR2EN));

            RCC -> PLLCFGR   |= (RCC_PLLCFGR_PLL2VCOSEL_WIDE_RANGE) |
                                (RCC_PLLCFGR_PLL2RGE_8MHz_16MHz)    |
                                (RCC_PLLCFGR_DIVP2EN)               |
                                (RCC_PLLCFGR_PLL2FRACEN);

            RCC -> PLL2DIVR  &= ~((RCC_PLL2DIVR_N2) |
                                  (RCC_PLL2DIVR_P2));

            RCC -> PLL2DIVR  |= (RCC_PLL2DIVR_N2_122) |
                                (RCC_PLL2DIVR_P2_8);
            RCC -> D2CCIP1R &= ~(RCC_D2CCIP1R_SPI123SEL);
                RCC -> D2CCIP1R |=  (RCC_D2CCIP1R_SPI123SEL_PLL2_P_CK);

                RCC -> CR &= ~(RCC_CR_PLL2ON);
                RCC -> CR |=  (RCC_CR_PLL2ON);

                while (!((RCC -> CR) & (RCC_CR_PLL2RDY)));

                SPI1->I2SCFGR = 0x00;
                    SPI1->CFG1 &= ~((SPI_CFG1_RXDMAEN) |
                                    (SPI_CFG1_TXDMAEN));

                                     SPI1->CFG1 |= (SPI_CFG1_RXDMAEN) |
                                                   (SPI_CFG1_TXDMAEN);
                                     SPI1->I2SCFGR |= (SPI_I2SCFGR_MCKOE)              |
                                                      (SPI_I2SCFGR_I2SDIV_2)           |
                                                      (SPI_I2SCFGR_DATFMT_LEFT)        |
                                                      (SPI_I2SCFGR_I2SSTD_I2S)         |
                                                      (SPI_I2SCFGR_I2SCFG_MASTER_FULL) |
                                                      (SPI_I2SCFGR_I2SMOD_I2S);
                                     SPI1->I2SCFGR |= (SPI_I2SCFGR_DATLEN_24BIT);
                                                SPI1->I2SCFGR |= (SPI_I2SCFGR_CHLEN_32BIT);


                                                     SPI1->CR1 |= SPI_CR1_SPE;
                                                     SPI1->CR1 |= SPI_CR1_CSTART;

}

void INIT_INTERRUPT() {
    NVIC_SetPriority(DMA1_Stream0_IRQn,0);
    NVIC_EnableIRQ(DMA1_Stream0_IRQn);
}

int main(void) {

    INIT_CLOCK();
    INIT_GPIO();
    INIT_DMA();
    INIT_I2S();
    INIT_INTERRUPT();

    while (1) {

        if (I2S1_HC == 1) {
            for (int i = 0; i < 2; i++) {
                I2S1_TxBUFF[i] = I2S1_RxBUFF[i];
            }
            I2S1_HC = 0;
        }

        if (I2S1_TC == 1) {
            for (int i = 2; i < 4; i++) {
                I2S1_TxBUFF[i] = I2S1_RxBUFF[i];
            }
            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;
    }
}

Update 5:

Tried using the HAL drivers to get it going but its experiencing the same thing.

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; 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"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

I2S_HandleTypeDef hi2s1;
DMA_HandleTypeDef hdma_spi1_tx;
DMA_HandleTypeDef hdma_spi1_rx;

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_I2S1_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
uint16_t rxBuf[8];
uint16_t txBuf[8];
float l_a0, l_a1, l_a2, l_b1, l_b2, lin_z1, lin_z2, lout_z1, lout_z2;
float r_a0, r_a1, r_a2, r_b1, r_b2, rin_z1, rin_z2, rout_z1, rout_z2;
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_I2S1_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  HAL_I2SEx_TransmitReceive_DMA (&hi2s1, txBuf, rxBuf, 4);

  //left-channel, High-Pass, 1kHz, fs=96kHz, q=0.7
   l_a0 = 0.9543457485325094f;
   l_a1 = -1.9086914970650188f;
   l_a2 = 0.9543457485325094f;
   l_b1 = -1.9066459797557103f;
   l_b2 = 0.9107370143743273f;

   //right-channel, Low-Pass, 1kHz, fs)96 kHz, q=0.7
   r_a0 = 0.0010227586546542474f;
   r_a1 = 0.002045517309308495f;
   r_a2 = 0.0010227586546542474f;
   r_b1 = -1.9066459797557103f;
   r_b2 = 0.9107370143743273f;

  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

int Calc_IIR_Left (int inSample) {
    float inSampleF = (float)inSample;
    float outSampleF =
            l_a0 * inSampleF
            + l_a1 * lin_z1
            + l_a2 * lin_z2
            - l_b1 * lout_z1
            - l_b2 * lout_z2;
    lin_z2 = lin_z1;
    lin_z1 = inSampleF;
    lout_z2 = lout_z1;
    lout_z1 = outSampleF;

    return (int) outSampleF;
}

int Calc_IIR_Right (int inSample) {
    float inSampleF = (float)inSample;
    float outSampleF =
            r_a0 * inSampleF
            + r_a1 * rin_z1
            + r_a2 * rin_z2
            - r_b1 * rout_z1
            - r_b2 * rout_z2;
    rin_z2 = rin_z1;
    rin_z1 = inSampleF;
    rout_z2 = rout_z1;
    rout_z1 = outSampleF;

    return (int) outSampleF;
}

void HAL_I2SEx_TxRxHalfCpltCallback(I2S_HandleTypeDef *hi2s){

    //restore signed 24 bit sample from 16-bit buffers
    int lSample = (int) (rxBuf[0]<<16)|rxBuf[1];
    int rSample = (int) (rxBuf[2]<<16)|rxBuf[3];

    // divide by 2 (rightshift) -> -3dB per sample
    lSample = lSample>>1;
    rSample = rSample>>1;

    //sum to mono
    lSample = rSample + lSample;
    rSample = lSample;

    //run HP on left channel and LP on right channel
    lSample = Calc_IIR_Left(lSample);
    rSample = Calc_IIR_Right(rSample);

    //restore to buffer
    txBuf[0] = (lSample>>16)&0xFFFF;
    txBuf[1] = lSample&0xFFFF;
    txBuf[2] = (rSample>>16)&0xFFFF;
    txBuf[3] = rSample&0xFFFF;
}

void HAL_I2SEx_TxRxCpltCallback(I2S_HandleTypeDef *hi2s){

    //restore signed 24 bit sample from 16-bit buffers
    int lSample = (int) (rxBuf[4]<<16)|rxBuf[5];
    int rSample = (int) (rxBuf[6]<<16)|rxBuf[7];

    // divide by 2 (rightshift) -> -3dB per sample
    lSample = lSample>>1;
    rSample = rSample>>1;

    //sum to mono
    lSample = rSample + lSample;
    rSample = lSample;

    //run HP on left channel and LP on right channel
    lSample = Calc_IIR_Left(lSample);
    rSample = Calc_IIR_Right(rSample);

    //restore to buffer
    txBuf[4] = (lSample>>16)&0xFFFF;
    txBuf[5] = lSample&0xFFFF;
    txBuf[6] = (rSample>>16)&0xFFFF;
    txBuf[7] = rSample&0xFFFF;
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Supply configuration update enable
  */
  HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
  /** Configure the main internal regulator output voltage
  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);

  while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
  /** Macro to configure the PLL clock source
  */
  __HAL_RCC_PLL_PLLSOURCE_CONFIG(RCC_PLLSOURCE_HSI);
  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_DIV1;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 4;
  RCC_OscInitStruct.PLL.PLLN = 60;
  RCC_OscInitStruct.PLL.PLLP = 2;
  RCC_OscInitStruct.PLL.PLLQ = 2;
  RCC_OscInitStruct.PLL.PLLR = 2;
  RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;
  RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
  RCC_OscInitStruct.PLL.PLLFRACN = 0;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
                              |RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
  RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief I2S1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_I2S1_Init(void)
{

  /* USER CODE BEGIN I2S1_Init 0 */

  /* USER CODE END I2S1_Init 0 */

  /* USER CODE BEGIN I2S1_Init 1 */

  /* USER CODE END I2S1_Init 1 */
  hi2s1.Instance = SPI1;
  hi2s1.Init.Mode = I2S_MODE_MASTER_FULLDUPLEX;
  hi2s1.Init.Standard = I2S_STANDARD_PHILIPS;
  hi2s1.Init.DataFormat = I2S_DATAFORMAT_24B;
  hi2s1.Init.MCLKOutput = I2S_MCLKOUTPUT_ENABLE;
  hi2s1.Init.AudioFreq = I2S_AUDIOFREQ_96K;
  hi2s1.Init.CPOL = I2S_CPOL_LOW;
  hi2s1.Init.FirstBit = I2S_FIRSTBIT_MSB;
  hi2s1.Init.WSInversion = I2S_WS_INVERSION_DISABLE;
  hi2s1.Init.Data24BitAlignment = I2S_DATA_24BIT_ALIGNMENT_LEFT;
  hi2s1.Init.MasterKeepIOState = I2S_MASTER_KEEP_IO_STATE_DISABLE;
  if (HAL_I2S_Init(&hi2s1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN I2S1_Init 2 */

  /* USER CODE END I2S1_Init 2 */

}

/**
  * Enable DMA controller clock
  */
static void MX_DMA_Init(void)
{

  /* DMA controller clock enable */
  __HAL_RCC_DMA1_CLK_ENABLE();

  /* DMA interrupt init */
  /* DMA1_Stream0_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);
  /* DMA1_Stream1_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);

}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();

}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
\$\endgroup\$
9
  • \$\begingroup\$ What is the memory address of the buffer from which you're trying to transmit using DMA? Is it in one of the STM32H7's internal SRAM memory blocks? Which one? \$\endgroup\$
    – brhans
    Jun 4, 2021 at 1:58
  • \$\begingroup\$ @brhans I think I know where you getting at, but I haven't done anything to the linker. How can I find out? I can check it for you but I would hope its where the DMA can access \$\endgroup\$
    – Leoc
    Jun 4, 2021 at 3:15
  • \$\begingroup\$ That is what I'm getting at. When I started a new project on an STM32H7 last year I had so much trouble getting DMA working until I realized that my compiler/linker had placed all my variables in the DTCM RAM block. This is great for 'normal' variables because it's 'closely coupled' to the core, but only the core can access it - not the DMA or any other module, because it's not on the shared bus between them. You need to make sure that your DMA buffers are in one of the other RAM blocks like the AXISRAM which DMA can access. \$\endgroup\$
    – brhans
    Jun 4, 2021 at 5:13
  • \$\begingroup\$ This would be my very first time doing anything of that sort, how would I go about if its actually in the DTCM region or the ITCM? \$\endgroup\$
    – Leoc
    Jun 4, 2021 at 5:14
  • \$\begingroup\$ If you look in the map file generated by the linker you should find your buffer variables with their addresses. Check the memory map in the STM32H7 ref manual to see which RAM block they're in. If they're in DTCM or ITCM then you'll probably have to edit your linker script to either move all your variables to a different block, or create a new section in another block and tell your compiler to locate your DMA buffers in that section. \$\endgroup\$
    – brhans
    Jun 4, 2021 at 5:19

1 Answer 1

0
\$\begingroup\$

Found the problem.

I am using the STM32H753ZI nucleo and it has PA7 at three different places. 1/3 PA7 pin's worked.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.