/var/www/restricted/ssh/stm32/www/stm32circle/ STM CircleOS forum / [USART/IRDA] Problem while sending a string

Username:     
Password:     
             

Forum

# 1   2010-05-26 09:03:26 [USART/IRDA] Problem while sending a string

matmout
Member
From: Grenoble
Registered: 2010-05-10
Posts: 12

[USART/IRDA] Problem while sending a string

Hello,

I'm trying to make a small library for those who want to send string between 2 Primer2 over infrared.

I managed to send and receive one char (pressing primer2 button). However, my functions putString and getString don't work as expected. I try to send this string : "12345678". The receiver gets "11234567" or "81234567" and freezes sometimes.

Can anyone help me please ?

Thank you in advance

$1

Code:

void IRDA_Init(void)
{
    // Save old clock frequency
    OldPLLFreq = UTIL_GetPll();
    
    //Enable clock
    RCC_APB2PeriphClockCmd(
        RCC_APB2Periph_GPIOD | 
        RCC_APB2Periph_AFIO | 
        RCC_APB2Periph_USART1, ENABLE);
    UTIL_SetPll ( SPEED_VERY_HIGH );
    
    // Init IrDA
    IRDA_GPIO_Configuration();
    IRDA_USART_Configuration();
}

$1

Code:

    USART_InitTypeDef USART_InitStructure;

    USART_InitStructure.USART_BaudRate = 115200;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

    /* Configure the USART1 */
    USART_Init(USART1, &USART_InitStructure);
    
    /* Enable the USART1 */
    USART_Cmd(USART1, ENABLE);

    /* Set the USART1 prescaler */
    USART_SetPrescaler(USART1, 0x1);

    /* Configure the USART1 IrDA mode */
    USART_IrDAConfig(USART1, USART_IrDAMode_Normal);
    
    /* Enable the USART1 IrDA mode */
    USART_IrDACmd(USART1, ENABLE);

    // CS Irda  = 1
    GPIO_ResetBits(GPIOD, GPIO_Pin_8);

$1

Code:

void IRDA_PutChar(char c)
{
    // Send a char...
    USART_SendData(USART1, c);

    // ... wait until the char is sended
    while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET) ;
}

$1

Code:

char IRDA_GetChar(void)
{
    char c;

    // Wait for incomming char...
    while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET) ;
    
    // ... get it...
    c = USART_ReceiveData(USART1);
    
    // Char filter
    if ( (c >= 0x20 && c <= 0x7E) || c == 0x2 || c == 0x3)
        return c;
    
    // Return NUL (null)
    return 0x0;
}

$1

Code:

void IRDA_PutString(char* s, u8 length)
{
    if (*s == 0x0 || length < 1 || length > MAX_STRING_SIZE)
        return;
    
    u8 idx = 0;
    
    while (idx < length && s[idx] != '\0')
    {
        IRDA_PutChar(s[idx++]);
    }
}

$1

Code:

void IRDA_GetString(char* buffer)
{
    u8 idx = 0;
    char c;
    
    while(idx < 8)
    {
        buffer[idx++] = IRDA_GetChar();
    }

    buffer[idx] = '\0';
}

Last edited by matmout (2010-05-26 11:43:47)

Offline

 

# 2   2010-05-26 09:15:03 [USART/IRDA] Problem while sending a string

ntrf.zns
Member
From: Belgorod, Russia
Registered: 2009-11-01
Posts: 134

Re: [USART/IRDA] Problem while sending a string

Code:

while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET) ;

you should wait for register to become SET! Otherwise you are reading the previous value in the next call.

Offline

 

# 3   2010-05-26 11:41:31 [USART/IRDA] Problem while sending a string

matmout
Member
From: Grenoble
Registered: 2010-05-10
Posts: 12

Re: [USART/IRDA] Problem while sending a string

With this code, used in IRDA_GetChar function :

Code:

while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET) ;

don't you think it waits until the register get ready (active waiting with ";") ?

When I do $1, how can I clear the register and switch to the next value ? Should I use $1 ?

And by the way, what is the difference between that two signals : $1 and $1 ?

Thank you in advance

Last edited by matmout (2010-05-26 11:42:42)

Offline

 

# 4   2010-05-26 13:27:02 [USART/IRDA] Problem while sending a string

ntrf.zns
Member
From: Belgorod, Russia
Registered: 2009-11-01
Posts: 134

Re: [USART/IRDA] Problem while sending a string

Oops! Sorry about that. Didn't noticed you're using == instead of != .

Sometimes it much better to wait for specific signal before you're sending/receiving the byte. This way you have more time to prepare the data (however it won't make any difference on low speed).

Datasheet says that reading incoming byte in enough to clear the RXE byte. In my program i've been clearing RXNE flag after reading the value anyway. Here is my IRQ handler showing it:

Code:

void UART2_IRQHandler (void)
{
    if(USART2_SR & (1 << 5)) //Received byte
    {
        char d = USART2_ReadByte();
        USART2_SR &= ~(1 << 5); //Reset RXNE just in case
        //if(d >= 0x20 || d == '\n') DRAW_Putc(d);
        ModemContext.handler(ModemContext,d,false);
    }
    if((USART2_SR & (1 << 7)) && SendOut) //Transmited byte
    {
        char d = *SendOut; SendOut++;
        
        if(d) USART2_WriteByte(d);
        else{ 
            SendOut = NULL;
            USART2_DisableTX();
        }
    }
}

TXE tels you it's clear to write next byte but previous byte is still being sent.
TC means that all transfer is complete and line is free now.
To maintain continuous comunication you need to write bytes when TXE=1 and TC=0.

Last edited by ntrf.zns (2010-05-26 13:29:54)

Offline

 

# 5   2010-05-26 16:50:58 [USART/IRDA] Problem while sending a string

matmout
Member
From: Grenoble
Registered: 2010-05-10
Posts: 12

Re: [USART/IRDA] Problem while sending a string

can you tell me what the variable USART2_SR is exactly ?

Offline

 

# 6   2010-05-26 17:02:50 [USART/IRDA] Problem while sending a string

fdocteur
New member
Registered: 2010-05-10
Posts: 1

Re: [USART/IRDA] Problem while sending a string

I don't know if it can answer to your question:
USART2_SR & (1 << 5) stands for a test on the RXNE flag. If this flag == 1, so "Received data is ready to be read." according to the stm32F10x_ref_manual (p459) smile

Offline

 

# 7   2010-05-26 17:35:05 [USART/IRDA] Problem while sending a string

ntrf.zns
Member
From: Belgorod, Russia
Registered: 2009-11-01
Posts: 134

Re: [USART/IRDA] Problem while sending a string

USART2_SR is one of USART registers. You can access it as USART2->SR if you're using CMSIS or ST-LIB. Code is using my own library.

Here is a rewrite using CMSIS (should work with ST-LIB as well):

Code:

char *SendOut = NULL;

void UART2_IRQHandler (void)
{
    if(USART2->SR & USART_SR_RXNE) //Received byte
    {
        char d = USART2->DR;
        USART2->SR &= ~(USART_SR_RXNE); //Reset RXNE just in case
        //if(d >= 0x20 || d == '\n') DRAW_Putc(d);
        ModemContext.handler(ModemContext,d,false); // <-- Add your handler here
    }
    if((USART2->SR & USART_SR_RXNE) && SendOut) //Transmited byte
    {
        char d = *SendOut; SendOut++;
        
        if(d) USART2->DR = d;
        else{ 
            SendOut = NULL;
            USART2->CR1 &= ~(USART_CR1_TE);//Disable transmiter
        }
    }
}

void SendCommand(const char* cmd)
{
    SendOut = cmd;
    USART2->DR = (*SendOut); SendOut++;
    USART2->CR1 |= (USART_CR1_TE);//Enable transmiter
}

Last edited by ntrf.zns (2010-05-26 17:41:10)

Offline

 

# 8   2010-05-28 15:36:57 [USART/IRDA] Problem while sending a string

matmout
Member
From: Grenoble
Registered: 2010-05-10
Posts: 12

Re: [USART/IRDA] Problem while sending a string

There are somethings I do not completly understand. For my project, I use $1 as library. So when I'm working on USART/IR, I use functions like $1, etc. Should I use register flag to lead my project ?

For the time being, I don't want to use interruption for sending/receiving string. I think it's possible, don't you ?

After reading some pages of the STM32F10x_ref_manual, I've tried to understand what is wrong in my code. The manual says that before sending data, the transmiter send a idle signal. Thus, in my receiver application for Primer2, in the $1, I've something like below :

Code:

if (USART_GetFlagStatus(USART1, USART_FLAG_IDLE) == SET)
{
                IRDA_GetString(buffer);
}
        
DRAW_DisplayString( 5, 76, buffer, 4);

Is-it wrong ? I'm asking this because my app freeze (waits in a while-loop) after my transmiter sends it chars. I've put a framecounter in order to detect when my app freezes. It freezes after receiving 4 expected chars. If I try to send someother chars, the framecounter increaments by one. Do you see what I mean ?

Btw, I changed my PutChar function to :

Code:

void IRDA_PutChar(char c)
{
    // ... wait until the TX register is empty
    // If I uncomment the lign below it stills work (not correctly however)
    // while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET) ;

    // Send a char...
    USART_SendData(USART1, c);
    
    while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) ;

}

Can anyone tell me more about my mistakes please ?

After more tests, I noticed that the 1st time I send the string "1234", I receive "1123" and next "1234". Can someone explain me why ?



I've read somewhere on the forum that I've better to use an other USART (USART2 or 3). Is this really important for IRDa ?

Thank you in advance.

Offline

 

# 9   2010-06-01 10:06:21 [USART/IRDA] Problem while sending a string

matmout
Member
From: Grenoble
Registered: 2010-05-10
Posts: 12

Re: [USART/IRDA] Problem while sending a string

Ok, I managed to send a string without any problem, using interrupts smile Thank you !

Offline

 

Board footer