I'm trying to use the internal beep generator of CS43L22 on my STM32F4 Discovery. I'm using the Hal libary and can access the Chip via I2C but only for 4 Bytes (read or write) then the function HAL_I2C_Master_Transmit() gets stuck.
I narrowed the stuck down to I2C_WaitOnMasterAddressFlagUntilTimeout() Lines(5084 to 5122) in stm32f4xx_hal_i2c.c. When using a stepwise debugging, the complete code works fine, running from Breaktpoint to Breakpoint it fails.
I'm using Keil µVision 5.15 and would like to use the Hal drivers as the project will get ported to a RTOS application.
If you need any other Information I will be happy to provide it.
What could cause the code to get stuck? And what to do to prevent it?
my main.c:
// main.c
#include "stm32f4xx.h"
#include "my_header.h"
int main(void){
I2C_HandleTypeDef I2C_Params; // declare Parameter Handle
I2S_HandleTypeDef I2S_Params; // declare Parameter Handle
HAL_StatusTypeDef I2C_State; // declare State handle
GPIO_InitTypeDef GPIOD_Params; // Declares the structure handle for the parameters of the reset pin on GPIOE
GPIO_InitTypeDef GPIOB_Params; // Declares the structure handle for the parameters of I2C on GPIOB
GPIO_InitTypeDef GPIOC_Params; // Declares the structure handle for the parameters of I2S on GPIOC
uint8_t send_data; // declare send data variable
uint8_t send_data_array[2]; // declare send data variable
uint8_t received_data; // declare received data variable
HAL_Init(); // Initialise Hal driver
// configure System Clock
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
/* Enable Power Control clock */
__PWR_CLK_ENABLE();
/* The voltage scaling allows optimizing the power consumption when the device is
clocked below the maximum system frequency, to update the voltage scaling value
regarding system frequency refer to product datasheet. */
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/* Enable HSE Oscillator and activate PLL with HSE as source */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 7;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
LED_Init(); // initialise LEDs
Set_State_Rd_LED(1); // turn on red LED
// Configure GPIOD for reset pin on CS43L22
RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN; //Enable the clock for GPIOD
GPIOD_Params.Pin = GPIO_PIN_4; // Select pin 4
GPIOD_Params.Mode = GPIO_MODE_OUTPUT_PP; //Selects normal output push-pull mode
GPIOD_Params.Speed = GPIO_SPEED_FAST; //Selects fast speed
GPIOD_Params.Pull = GPIO_PULLDOWN; //Selects pull-down activation
HAL_GPIO_Init(GPIOD, &GPIOD_Params); // Sets GPIOD into the modes specified in GPIOE_Params
// Configure GPIOB for SCL (PB6) and SDA (PB9) on I2C1
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN; //Enable the clock for GPIOA
GPIOB_Params.Pin = GPIO_PIN_6 | GPIO_PIN_9; // Selects pins 6 and 9
GPIOB_Params.Alternate = GPIO_AF4_I2C1; //Selects alternate function (I2C1)
GPIOB_Params.Mode = GPIO_MODE_AF_OD; //Selects alternate function open drain mode
GPIOB_Params.Speed = GPIO_SPEED_FAST; //Selects fast speed
//GPIOB_Params.Speed = GPIO_SPEED_FREQ_VERY_HIGH; //Selects fast speed
GPIOB_Params.Pull = GPIO_NOPULL; //Selects no pull-up or pull-down activation
//GPIOB_Params.Pull = GPIO_PULLUP; //Selects no pull-up activation
HAL_GPIO_Init(GPIOB, &GPIOB_Params); // Sets GPIOB into the modes specified in GPIOA_Params
RCC->APB1ENR |= RCC_APB1ENR_I2C1EN ; // Enables the clock for I2C1
RCC->APB1ENR |= RCC_APB1ENR_SPI3EN ; // Enables the clock for SPI3 (I2S)
// Configure GPIOC for 7(MCLK), 10(SCLK) and 12(SDIN) on I2S
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN; //Enable the clock for GPIOA
GPIOC_Params.Pin = GPIO_PIN_7 | GPIO_PIN_10 | GPIO_PIN_12; // Selects pins 7(MCLK), 10(SCLK) and 12(SDIN)
GPIOC_Params.Alternate = GPIO_AF6_SPI3; //Selects alternate function (I2C1)
GPIOC_Params.Mode = GPIO_MODE_AF_PP; //Selects alternate function open drain mode
GPIOC_Params.Speed = GPIO_SPEED_FAST; //Selects fast speed
GPIOC_Params.Pull = GPIO_NOPULL; //Selects no pull-up or pull-down activation
HAL_GPIO_Init(GPIOC, &GPIOC_Params); // Sets GPIOB into the modes specified in GPIOA_Params
I2S_Params.Instance = SPI3;
I2S_Params.Init.Mode = I2S_MODE_MASTER_TX;
I2S_Params.Init.Standard = I2S_STANDARD_PHILIPS;
I2S_Params.Init.DataFormat = I2S_DATAFORMAT_16B;
I2S_Params.Init.MCLKOutput = I2S_MCLKOUTPUT_ENABLE;
I2S_Params.Init.AudioFreq = I2S_AUDIOFREQ_48K;
I2S_Params.Init.CPOL = I2S_CPOL_LOW;
//I2S_Params.Init.ClockSource = I2S_CLOCK_PLL;
//I2S_Params.Init.FullDuplexMode = I2S_FULLDUPLEXMODE_DISABLE;
HAL_I2S_Init(&I2S_Params);
// Configure I2C
I2C_Params.Instance = I2C1;
I2C_Params.Init.ClockSpeed = 100000; // Set clock speed to 50 kHz
I2C_Params.Init.DutyCycle = I2C_DUTYCYCLE_2; // Set duty cycle
I2C_Params.Init.OwnAddress1 = 0x33; // set own adress 1
// I2C_Params.Init.OwnAddress1 = 0x00; // set own adress 1
I2C_Params.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; // set to 7-Bit adresses
I2C_Params.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED; // Disabel dual address mode
I2C_Params.Init.OwnAddress2 = 0; // set own adress 2
I2C_Params.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED; // General call disabled
I2C_Params.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED; // No Stretch disabled
// I2C_Params.Init.NoStretchMode = I2C_NOSTRETCH_ENABLE; // No Stretch enabled
// I2C_Params.Mode = HAL_I2C_MODE_MASTER; // set I2C to master
// HAL_I2C_MspInit(&I2C_Params); // configure I2C
__HAL_I2C_ENABLE(&I2C_Params); // Enable the I2C1
I2C_State = HAL_I2C_Init(&I2C_Params); // configure I2C
__HAL_I2S_ENABLE(&I2S_Params);
GPIOD->BSRR |= GPIO_PIN_4; //Sets the reset pin of CS43L22 high
// ceck value
send_data = 0x01; // address of chip ID
HAL_I2C_Master_Transmit(&I2C_Params, 0x94, &send_data, 1, 1000); // Write Address to read
HAL_I2C_Master_Receive(&I2C_Params, 0x94, &received_data, 1, 1000); // read Chip ID register
// ceck value
send_data = 0x01; // address of chip ID
HAL_I2C_Master_Transmit(&I2C_Params, 0x94, &send_data, 1, 1000); // Write Address to read
HAL_I2C_Master_Receive(&I2C_Params, 0x94, &received_data, 1, 1000); // read Chip ID register
I2C_State = HAL_I2C_IsDeviceReady(&I2C_Params, 0x0094, 10, 1000);
// ceck value
send_data = 0x01; // address of chip ID
HAL_I2C_Master_Transmit(&I2C_Params, 0x94, &send_data, 1, 1000); // Write Address to read
HAL_I2C_Master_Receive(&I2C_Params, 0x94, &received_data, 1, 1000); // read Chip ID register
Set_State_Or_LED(1); // turn on orange LED
};