/var/www/restricted/ssh/stm32/www/stm32circle/ STM CircleOS forum / I2S3 Problem - Always reading zeros

Username:     
Password:     
             

Forum

# 1   2010-06-17 14:18:57 I2S3 Problem - Always reading zeros

brothe_r
Member
Registered: 2010-04-08
Posts: 10

I2S3 Problem - Always reading zeros

Hi everyone,

I'm working on my (open) final career project (you can see it at www.easyeeg.com), and now I'm having problems with the I2S3 (using SPI3) of the STM32F103RDT6 (the 64 pin LQFP). I use the I2S3 as interface between the STM32 and a 24bit sigma-delta stereo ADC. There is something really odd: I'm always reading zeros.

I configured the I2S as Master Receive, and with the oscilloscope I can see the Master Clock, the Serial Clock, the Word Select signal, even the data of the ADC! So, the ADC is configured and working properly. All the signals are working in their correct frequencies (Master Clock for the ADC at 8MHz, for the rest just divide it, since I'm using the standard from Phillips). So, the peripheral is also working.

The RXNE flag is also working: it is usually 0, then I wait until it becomes 1, then I read the data, and that RXNE flag is automatically cleared, as it should be. Despite this, the data read at register DR is always 0... I'm using the functions in the standard STM32 Firmware Library from ST, although I also tried to read the DR register directly from memory.

The pin which seems not to be working is the pin 5 from the port B. So, I thought it could be an ESD (electrostatic discharge) issue. Under this approach, the input MOSFET stage should be blown. So, what I did was configure the PB5 as "Input floating" instead of an "Alternate Function", then a simple while(1) application was monitoring that pin, and when a 1 was detected, it turned a LED on, when 0, turned it off (I force that pin connecting it to Vcc or Gnd). The test succeeded. So, it isn't a ESD issue, since the input pin is reading correctly that data. Could it be a defect of the IC coming from the foundry? I'd like to know it before having to desolder to replace the whole IC... I also read the Errata sheet, where there seems to be a problem with the I2S, although I think it is not my case.

Another test: I tried to configure all the I2S and just leave the PB5 as input floating. The key behind the test was leaving working the I2S and a while(1) counting the times the PB5 is reading 1's, but then no signals are generated by the peripheral... :S

Another test: I also tried it with interrupts. It seemed to work, but also reading zeros. I turned on the LED when came into the ISR, turn it off when leaving. Looking the LED signal at the oscilloscope, I can see how it turns on and off 2 times per word, as it should be: 1 interrupt every 16bits.

The code related with I2S (by polling, that is, without interrupts) is as follows:

[...]
    /* Enable peripheral clock*/
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);

[...]

    GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);

    /* Configure I2S3 (SPI3) pins: MCLK */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    /* Configure I2S3 (SPI3) pins: BCLK and ADCDAT */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_5;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    /* Configure I2S3 (SPI3) pins: ADCLRC (WS) */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

[...]

    /* I2S peripheral configuration */
    I2S_InitStructure.I2S_Standard = I2S_Standard_Phillips;
    I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_24b; /* I also tried it with 32b... nothing */
    I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Enable;
    I2S_InitStructure.I2S_AudioFreq = I2S_AudioFreq_8k;
    I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low;

    I2S_InitStructure.I2S_Mode = I2S_Mode_MasterRx;
    I2S_Init(SPI3, &I2S_InitStructure);

    I2S_Cmd(SPI3, ENABLE);

[...]

    while(isButtonPressed() == FALSE)
    {
        while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) == RESET);
        SPI_I2S_ClearFlag(SPI3, SPI_I2S_FLAG_RXNE); /* It is not really necessary, it makes no difference. It is cleared when the DR is read */
        temp = SPI_I2S_ReceiveData(SPI3);  /* Temp is ALWAYS 0... :-( */
    }
    PowerDeviceOFF();

[...]

In the last while(isButtonPressed()...) I know I should separate the temp variable into 4 variables -> 16 bit for each half word received, 2 words (right and left). But I'm just trying to read something different than 0. I'm watching the "temp" variable through the Keil software, with a SWD debugger.

I'm desperate, I don't know what else I can do... Please help! Thank you in advance!

Last edited by brothe_r (2010-06-17 14:30:25)

Offline

 

# 2   2010-06-18 07:12:18 I2S3 Problem - Always reading zeros

yrt
Administrator
From: Grenoble-France
Registered: 2008-06-11
Posts: 520
Website

Re: I2S3 Problem - Always reading zeros

Indeed PB5 is an input (I2S3 _SD), but it must be configured as Alternate function for running as I2S peripheral. I think it should be configured to open drain with the parameter "GPIO_Mode_AF_OD", and not "GPIO_Mode_AF_PP" that means alternate output.

Offline

 

# 3   2010-06-18 09:06:37 I2S3 Problem - Always reading zeros

brothe_r
Member
Registered: 2010-04-08
Posts: 10

Re: I2S3 Problem - Always reading zeros

Hi yrt,

Thanks for your response. It makes no difference. In fact, I took the example from the Keil folder (C:\Keil\ARM\Examples\ST\STM32F10xFWLib\Examples\I2S\Interrupt), where they are using "GPIO_Mode_AF_PP". Furthermore, I'm also using SPI2 (as SPI, not I2S) and the MISO works correctly with GPIO_Mode_AF_PP.

Maybe it could be solved changing the IC, otherwise I don't know what else it can be. I even tried to configure register by register instead of using the STM32 FW Library, but I get the same result: always reading zeros...

Thanks you! I'm hoping a miracle, I've try it everything...

EDIT: I forgot to add this. I checked with the scope, and just changing the GPIO_Mode_AF_PP for GPIO_Mode_AF_OD, the peripheral is not generating the clock signals, nor the word select... The Master Clock has few amplitude (it seems like if it were an internal capacitive coupling), and the Serial clock and Word Select is non existent. When I go back to GPIO_Mode_AF_PP it works again (well "works...", it reads zeros, but almost it generate the clocks and the ADC responses...). It is REALLY strange... At so low level, I think it can only be explained by the person who design the device in a microelectronic level (you know, gates, masks, and so on)...

Last edited by brothe_r (2010-06-18 09:23:29)

Offline

 

# 4   2010-06-18 10:16:20 I2S3 Problem - Always reading zeros

brothe_r
Member
Registered: 2010-04-08
Posts: 10

Re: I2S3 Problem - Always reading zeros

Wow, I'm quite perplexed... It seems a hardware bug, although I should confirm it with some other tests. Right now I have been convinced about I'm not reading data from SPI3->DR register because I was always seeing zeros when I used the SWD debugger. But then I thought that it could be a good test to try it without the debugger.

Well, the only outputs from my system are the SWD, a LED, and a wireless radio. In fact, I also have some DACs, but then I should see the data with an scope. I don't have ready the radio. So, I can't know the exact data (yet). That was the test:

    while(isButtonPressed() == FALSE)
    {
        while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) == RESET);
        temp[tempIndex] = SPI_I2S_ReceiveData(SPI3);
        if(temp[0] != 0)
        {
            AssignLEDstatus(1);
            Delay(0x1000000);
            PowerDeviceOFF();
        }
        tempIndex++;
        if(tempIndex > 3)
            tempIndex = 0;
    }

What I'm doing in this way, is turning ON the LED when the data I read from the I2S is different from 0. That is my success criteria, since I'm always reading zeros. The key of doing this is that I can see whether I'm reading zeros or not without the SWD debugger.

Surprise! When I use the SWD, I always see temp[0], temp[1], temp[2] and temp[3] as zeros, but when I run the same code without the SWD, the LED turns on, and the device turns off... amazing. The SWD seems to work properly, since I'm seeing other variables changing in real time.

Any idea about this strange behavior? As soon as I'm able to send data via wireless I'll post my results, to see if the read data is correct, and if we can close this post in a correct way and with some conclusions for others.

Offline

 

# 5   2010-06-18 12:46:04 I2S3 Problem - Always reading zeros

yrt
Administrator
From: Grenoble-France
Registered: 2008-06-11
Posts: 520
Website

Re: I2S3 Problem - Always reading zeros

I'm sorry if I was not clear, but I said only that the signal SD should be configured with GPIO_Mode_AF_OD. Of course the clock and word select must be configured with GPIO_Mode_AF_PP. It's the case for all peripherals : inputs or bidirectionals signals -> OD, outputs -> PP

Offline

 

# 6   2010-06-18 14:35:31 I2S3 Problem - Always reading zeros

brothe_r
Member
Registered: 2010-04-08
Posts: 10

Re: I2S3 Problem - Always reading zeros

Hi yrt,

Yes, you were perfectly clear :-) The behavior I explained happened only configuring the SD as GPIO_Mode_AF_OD. That is really strange, I know, but the only difference between running the code when I see the clocks & WS and when I don't see them, is when I configure JUST the SD line as GPIO_Mode_AF_OD...

Anyway, I think it is problem of the SWD, because I see the I2S data when I don't have the SWD connected. Really strange...

Maybe I'm not clear with my problem... I try to give as much info as I can.

Thank you!

Offline

 

# 7   2010-06-20 20:26:42 I2S3 Problem - Always reading zeros

brothe_r
Member
Registered: 2010-04-08
Posts: 10

Re: I2S3 Problem - Always reading zeros

Hi again,

I'm 100% sure the problem is related with the SWD. The board where I use the ADC & I2S also has a wireless IC (a nRF24L01). I configured it, and now I can send data from that board to a second module. So, now I have the SWD connected to that second module (the wireless receiver), and I can read the data sent from the main board. I can see that data, so, the I2S is working propery, and I'm not reading zeros :-) Again, when I connect the SWD to the main board (without changing the firmware), I read zeros. It is clear: I read zeros when the SWD is connected.

Well, the problem is solved. Despite this, I'd like to know why... Does anyone know it?

Thank you!

Last edited by brothe_r (2010-06-22 07:19:38)

Offline

 

Board footer