cancel
Showing results for 
Search instead for 
Did you mean: 

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

Dieter Steinwedel
Associate II
Posted on January 02, 2017 at 11:21

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 5.5 and 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?

2 REPLIES 2
Dieter Steinwedel
Associate II
Posted on January 02, 2017 at 18:29

I have forgotten to write, that I'm using HAL V1.5.1.

BTW, I verified my measurements with the example project STM32F769I-Discovery/Examples/SPDIFRX/SPDIFRX_Loopback with setting a breakpoint.

Can anyone confirm my measurements with the example?

Dieter Steinwedel
Associate II
Posted on February 18, 2017 at 09:21

After a while, I've understood, that I've misinterpreted the data. If you enable following flags:

    SpdifrxHandle.Init.PreambleTypeMask = SPDIFRX_PREAMBLETYPEMASK_OFF;

    SpdifrxHandle.Init.ChannelStatusMask = SPDIFRX_CHANNELSTATUS_OFF;

    SpdifrxHandle.Init.ParityErrorMask = SPDIFRX_PARITYERRORMASK_OFF;

    SpdifrxHandle.Init.ValidityBitMask = SPDIFRX_VALIDITYMASK_OFF;

you will be able to understand the received data on reading the MCU Spec 37.5.5 (LSB) or rather 37.5.6 (MSB).

I hope, it helps you, too.