Problema I2C en el descubrimiento STM32F4 al conectarse a CS43L22

0

Estoy tratando de usar el generador interno de pitidos de CS43L22 en mi STM32F4 Discovery. Estoy usando la biblioteca HAL y puedo acceder al Chip a través de I2C, pero solo para 4 bytes (lectura o escritura), la función HAL_I2C_Master_Transmit() se atasca.

Reduje el atascado a I2C_WaitOnMasterAddressFlagUntilTimeout() Líneas (5084 a 5122) en stm32f4xx_hal_i2c.c. Cuando se utiliza una depuración paso a paso, el código completo funciona bien, al ejecutarse desde Breaktpoint hasta Breakpoint, falla.

Estoy usando Keil µVision 5.15 y me gustaría usar los controladores HAL ya que el proyecto se transferirá a una aplicación RTOS. Si necesita cualquier otra información, estaré encantado de proporcionarla.

¿Qué podría hacer que el código se atasque? ¿Y qué hacer para evitarlo?

mi 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

};
    
pregunta BKE

1 respuesta

1

Nunca activa el reloj para el puerto C de GPIO debido a un error de copiar y pegar.

Cambia esto:

RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN; //Enable the clock for GPIOA

A esto:

RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN; //Enable the clock for GPIOC

El depurador puede hacer esto por usted y esa es la razón por la que funciona cuando se realiza la depuración.

    
respondido por el staringlizard

Lea otras preguntas en las etiquetas