Author Topic: I no longer can't get I2S working on a STM32H7 anymore. Need help.  (Read 1937 times)

0 Members and 1 Guest are viewing this topic.

Offline crisroxmysocTopic starter

  • Newbie
  • Posts: 2
  • Country: ca
Hey everyone! I am brand new here and looking forward in the future replies from everyone!

for the past 3 days I have been trying to get my I2S bus transmitting data back into my DAC via the MOSI pin.

Using the STM32H753ZI MCU:
https://www.st.com/resource/en/reference_manual/dm00314099-stm32h742-stm32h743753-and-stm32h750-value-line-advanced-armbased-32bit-mcus-stmicroelectronics.pdf

This is not my first time me doing bare metal nor setting up the I2S, I had a prototype board with everything working. I wanted to upgrade the code from doing 32-bit DSP processing to 64-bit then when I went to go try out the I2S nothing is transmitting.

So I reverted back to the original code and now it never wants to transmit.

I feel like I am over looking something, I just need a new pair of eyes on this to show me where I went wrong.

What I have confirmed thus far so I dont waste your guys time are.

- Memory is in the right region for DMA
- SPI & DMA registers reporting 0 errors
- Checked the GPIO, RCC, I2S, DMA registers are set correctly
- The WS, SCLK, and MCLK are being produced correctly at 96kHz
- Used old code that was confirmed working, is no longer working

To make sure I was doing something wrong I resorted to using the HAL for the I2S and its experiencing the same thing how is that even possible.

Bare - Metal Code (Up to date):
Code: [Select]
/* 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;
    }
}

HAL Code: (Up to Date):
Code: [Select]
/* 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****/


Please if anyone can help me that would be amazing, three days at this and its starting to get to me.

Whats working thus far is the receive, I can see the Rx Buffer accepting data no problem and I can also see the Tx Buffer being populated as well.
« Last Edit: June 07, 2021, 10:24:44 pm by crisroxmysoc »
 

Offline MasterT

  • Frequent Contributor
  • **
  • Posts: 785
  • Country: ca
Re: I no longer can't get I2S working on a STM32H7 anymore. Need help.
« Reply #1 on: June 07, 2021, 10:45:02 pm »
I can't find in your HAL code spi_post_init part (example H743zi):
Code: [Select]
void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
 
  if(hspi->Instance == SPI2) {
 
    __HAL_RCC_SPI2_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**SPI2 GPIO Configuration   
      PB12     ------> SPI2_NSS
      PB13     ------> SPI2_SCK
      PB15     ------> SPI2_MOSI
    */
    GPIO_InitStruct.Pin       = GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_15;
    GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull      = GPIO_NOPULL;
    GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    hdma_spi2_rx.Instance                 = DMA1_Stream2;
    hdma_spi2_rx.Init.Request             = DMA_REQUEST_SPI2_RX;
    hdma_spi2_rx.Init.Direction           = DMA_PERIPH_TO_MEMORY;
    hdma_spi2_rx.Init.PeriphInc           = DMA_PINC_DISABLE;
    hdma_spi2_rx.Init.MemInc              = DMA_MINC_ENABLE;
    hdma_spi2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
    hdma_spi2_rx.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
    hdma_spi2_rx.Init.Mode                = DMA_CIRCULAR;
    hdma_spi2_rx.Init.Priority            = DMA_PRIORITY_VERY_HIGH;
    hdma_spi2_rx.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;

    if(HAL_DMA_Init(&hdma_spi2_rx) != HAL_OK) {
      Error_Handler();
      }

    __HAL_LINKDMA( hspi, hdmarx, hdma_spi2_rx);

//    HAL_NVIC_SetPriority(SPI2_IRQn, 0, 0);
  //  HAL_NVIC_EnableIRQ(SPI2_IRQn);
  }
}

 

Offline crisroxmysocTopic starter

  • Newbie
  • Posts: 2
  • Country: ca
Re: I no longer can't get I2S working on a STM32H7 anymore. Need help.
« Reply #2 on: June 07, 2021, 10:56:08 pm »
Hi! Thank you for the reply. Can you further explain what you mean?

I would be using the MX_I2S1_Init? Right? I am not trying to setup the SPI register but the I2S register within the SPI.

Code: [Select]
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
  */
« Last Edit: June 07, 2021, 10:58:03 pm by crisroxmysoc »
 

Offline MasterT

  • Frequent Contributor
  • **
  • Posts: 785
  • Country: ca
Re: I no longer can't get I2S working on a STM32H7 anymore. Need help.
« Reply #3 on: June 08, 2021, 12:46:19 am »
I'm not an expert, but my arduino programming skills (nucleo-H743zi) teach me that it's not only right code written and called what important, but each line has to be called in correct sequence. For example, trying to set-up DMA channel with SPI-clock off very likely would put DMA in the error state. HAL driver usually initialized  DMA clock & interrupt,
Code: [Select]
void SPI2_DMA_Init(void)
{
  __HAL_RCC_DMA1_CLK_ENABLE();

  HAL_NVIC_SetPriority(DMA1_Stream2_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Stream2_IRQn);
}
than SPI() - I2S in your case, and just about to the end of SPI-I2S init function it's calling function I posted above HAL_SPI_MspInit() . AFAIK, there is "weak" definition prototype, but stm's CubeMX helps a lot to generate this part.

Though, probably your :
 MX_DMA_Init();
  MX_I2S1_Init();
needs to be split into 4 parts, quick init DMA, than SPI - config, than DMA again - full config of channel, and last part to set SPI-on
 

Online Siwastaja

  • Super Contributor
  • ***
  • Posts: 8168
  • Country: fi
Re: I no longer can't get I2S working on a STM32H7 anymore. Need help.
« Reply #4 on: June 27, 2021, 02:45:08 pm »
If old code which worked stopped working, don't overlook the possibility of damaged (ESD or otherwise) chip. I have indeed had a strange moment when an SPI in STM32 did not work - IIRC data was stuck at '0' - but the very same pins all worked perfectly in GPI or GPO mode, suggesting a software issue. Finally I just though "what the heck", desoldered and soldered in a new part, and that worked. So clearly there was damage inside the chip beyond the IO driver cells.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf