AnsweredAssumed Answered

Problem with msb/lsb and flags using the spdifrx hardware on a STM32F7

Question asked by Dieter Steinwedel on Jan 2, 2017
Latest reply on Feb 18, 2017 by Dieter Steinwedel

Hello,

 


I have a strange a strange behaviour using the spdifrx hardware on my STM32F769I-DISCO. I want to receive the IEC60958 subframes from the hardware but I get the data only without the preemble and all flags.
I have enabled the according flags on initializing the hardware. The second problem is the data alignment using the "SpdifrxHandle.Init.DataFormat" flag.

 

Using "SPDIFRX_DATAFORMAT_MSB" returns following bit structure:
D15-D0 followed by 16 zeros, i.e. 01101101 11011100 00000000 00000000

 

Using "SPDIFRX_DATAFORMAT_LSB" returns following bit structure:
8 zeros followed by D15-D0 followed by 8 zeros, i.e. 00000000 01101101 11011100 00000000

 

The MCU spec (DM00224583) describes in chapter 37.5.5 and 37.5.6 an different structure.

 

Here my code:

#include "stm32f7xx.h"
#include "stm32f769i_discovery.h"
#include "stm32f769i_discovery_lcd.h"

#define LAYER0_ADDRESS               (LCD_FB_START_ADDRESS)

static SPDIFRX_HandleTypeDef        SpdifrxHandle;
static uint32_t received_data_flow[64];

/**
  * @brief  System Clock Configuration
  *         The system Clock is configured as follow :
  *            System Clock source            = PLL (HSE)
  *            SYSCLK(Hz)                     = 216000000
  *            HCLK(Hz)                       = 216000000
  *            AHB Prescaler                  = 1
  *            APB1 Prescaler                 = 4
  *            APB2 Prescaler                 = 2
  *            HSE Frequency(Hz)              = 25000000
  *            PLL_M                          = 25
  *            PLL_N                          = 432
  *            PLL_P                          = 2
  *            PLL_Q                          = 9
  *            PLL_R                          = 7
  *            VDD(V)                         = 3.3
  *            Main regulator output voltage  = Scale1 mode
  *            Flash Latency(WS)              = 7
  * @param  None
  * @retval None
  */

static void SystemClock_Config(void)
{
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_OscInitTypeDef RCC_OscInitStruct;
  HAL_StatusTypeDef  ret = HAL_OK;

  /* Enable Power Control clock */
  __HAL_RCC_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 = 25;
  RCC_OscInitStruct.PLL.PLLN = 432;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 9;
  RCC_OscInitStruct.PLL.PLLR = 7;

  ret = HAL_RCC_OscConfig(&RCC_OscInitStruct);
  if(ret != HAL_OK)
  {
    while(1) { ; }
  }

  /* Activate the OverDrive to reach the 216 MHz Frequency */
  ret = HAL_PWREx_EnableOverDrive();
  if(ret != HAL_OK)
  {
    while(1) { ; }
  }

  /* 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;

  ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7);
  if(ret != HAL_OK)
  {
    while(1) { ; }
  }
}

void HAL_SPDIFRX_MspInit(SPDIFRX_HandleTypeDef *hspdif) {
  GPIO_InitTypeDef GPIO_InitStructure;
  RCC_PeriphCLKInitTypeDef rcc_clkex;

  __HAL_RCC_SPDIFRX_CLK_ENABLE();

  rcc_clkex.PeriphClockSelection = RCC_PERIPHCLK_SPDIFRX;
  rcc_clkex.I2sClockSelection = RCC_I2SCLKSOURCE_PLLI2S;
  rcc_clkex.PLLI2S.PLLI2SN = 400;
  rcc_clkex.PLLI2S.PLLI2SP = RCC_PLLI2SP_DIV4;
  HAL_RCCEx_PeriphCLKConfig(&rcc_clkex);

  /* Enable and set SPDIF Interrupt */
  HAL_NVIC_SetPriority(SPDIF_RX_IRQn,  0, 1);
  HAL_NVIC_EnableIRQ(SPDIF_RX_IRQn);

  /* GPIOs Configuration */
  /* RX1   <->   PG12 */
  /*configure SPDIFRX_IN1 PG12 pin */
  /* Enable SPDIF GPIO IN */

  GPIO_InitStructure.Pin       = GPIO_PIN_12;
  GPIO_InitStructure.Mode      = GPIO_MODE_AF_PP;
  GPIO_InitStructure.Pull      = GPIO_NOPULL;
  GPIO_InitStructure.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStructure.Alternate = GPIO_AF7_SPDIFRX;
  HAL_GPIO_Init(GPIOG, &GPIO_InitStructure);
}


void Error_Handler(void) {
     BSP_LED_Init(LED1);
     BSP_LED_On(LED1);
     while (1);
}

const char* to_binary(uint32_t x) {
     static char b[64];
     b[0] = '\0';

     uint8_t i = 0;
     for (uint32_t z = (1 << 31); z > 0; z >>= 1) {
          i++;
          strcat(b, ((x & z) == z) ? "1" : "0");
          if (i % 8 == 0) {
               strcat(b, " ");
          }
     }

     return b;
}

int main(void) {
     HAL_Init();

     SystemClock_Config();

     /* Initializing LCD */
     BSP_LCD_Init();
     BSP_LCD_LayerDefaultInit(0, LAYER0_ADDRESS);
     BSP_LCD_SelectLayer(0);
     BSP_LCD_Clear(LCD_COLOR_BLACK);
     BSP_LCD_SetFont(&Font12);
     BSP_LCD_SetTextColor(LCD_COLOR_WHITE);
     BSP_LCD_SetBackColor(LCD_COLOR_BLACK);

     /* Configure SPDIFRX Peripheral */
     SpdifrxHandle.Instance = SPDIFRX;
     HAL_SPDIFRX_DeInit(&SpdifrxHandle);

     SpdifrxHandle.Init.InputSelection = SPDIFRX_INPUT_IN1;
     SpdifrxHandle.Init.Retries = SPDIFRX_MAXRETRIES_15;
     SpdifrxHandle.Init.WaitForActivity = SPDIFRX_WAITFORACTIVITY_ON;
     SpdifrxHandle.Init.ChannelSelection = SPDIFRX_CHANNEL_A;
     SpdifrxHandle.Init.DataFormat = SPDIFRX_DATAFORMAT_MSB;
     SpdifrxHandle.Init.StereoMode = SPDIFRX_STEREOMODE_ENABLE;
     SpdifrxHandle.Init.PreambleTypeMask = SPDIFRX_PREAMBLETYPEMASK_ON;
     SpdifrxHandle.Init.ChannelStatusMask = SPDIFRX_CHANNELSTATUS_ON;
     if (HAL_SPDIFRX_Init(&SpdifrxHandle) != HAL_OK) {
          /* Initialization error */
          Error_Handler();
     }

     /* Grab some spdif data */
     HAL_SPDIFRX_ReceiveDataFlow(&SpdifrxHandle, (uint32_t *)received_data_flow, 64, 0xfff);

     /* Output grabbed data to LCD */
     for (uint32_t i = 0; i < 39; i++) {
          uint32_t data = received_data_flow[i];
          BSP_LCD_DisplayStringAt(0, LINE(i), (uint8_t *) to_binary(data), LEFT_MODE);
     }

     while (1);
}

 

Do I configure the hardware wrong or is it a bug?

Attachments

Outcomes