This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Setting S0RIR

Hi,

After receiving a command on the serial port I want to disable all interrupts and then wait for the serial port to receive a byte. The following code shows what I am doing.

IEN = 0 ;
_nop_() ;
_nop_() ;

while( !S0RIR ) ;
rxbyte = ( uint8_t ) S0TBUF ;
S0RIR = 0 ;

It appears that I never pass the while loop. Does disabling the serial rx interrupt stop S0RIR being set ? Any ideas ?

I am using a ST10F168.

Cheers

Elliot

Parents Reply Children
  • I have found a solution to my problem. The receive code needs to be as follows for it to work correctly.

    while( !S0RIR & !S0EIR ) ;
    rx_char = ( uint8_t ) S0RBUF ;
    S0RIR = 0 ;
    S0EIR = 0 ;
    
    I thought that the S0EIR flag was set simultaneously with the S0RIR flag from my reading of the manual. This appears not to the case ? Can anyone shed any light on this?

    I set S0CON to 0x90B7.

    Cheers

    Elliot

  • I thought that the S0EIR flag was set simultaneously with the S0RIR flag from my reading of the manual.

    I thought so too. According to the manual, in your piece of code

    while( !S0RIR & !S0EIR ) ;
    should have the save effect as
    while( !S0RIR ) ;
    If it's not the case, it looks like a chip bug to me. But I would investigate that further if I wanted to be sure.
    Anyway, having errors during reception is not a good thing. Besides, I would write
    while( !S0RIR && !S0EIR ) ;
    instead of
    while( !S0RIR & !S0EIR ) ;
    Both should do the same, but the latter can be confusing.

    Regards,
    - mike

  • while( !S0RIR & !S0EIR ) ;
    ... can be confusing.

    And quite probably generates more code if efficiency is a concern. The only time you would want the bitwise-AND versus the logical-AND in this context is when you need the side effects of evaluating the second operand (which is extremely unlikely to be the case here).

  • Hi Again

    This code works at 9600 baud but seems to have problems at higher rates and is contrary to the manual.

    uint8_t GetByte( void )
    {
    	uint8_t rx_char ;
    
    	while( !S0EIR && !S0RIR ) ;
    
    	rx_char = ( uint8_t ) S0RBUF ;
            S0RIR = 0 ;
    	S0EIR = 0 ;
    
    	return rx_char ;
    }
    

    but this code cause a reset

    uint8_t GetByte( void )
    {
    	uint8_t rx_char ;
    
    	while( !S0RIR ) ;
    
    	rx_char = ( uint8_t ) S0RBUF ;
            S0RIR = 0 ;
    
    	return rx_char ;
    }
    

    I am not using a watchdog and have no interrupts. Has anyone any theories on what might be happening ? This is driving me mad.

    Cheers

    Elliot

  • Well, without an in-circuit debugger you can never be sure what's going on. Besides, hardware problems is always a possibility (floating NMI pin, for example.)
    Set up debugging with Monitor166. Even if there is no external RAM in your target hardware, you should be able to debug small pieces of code with 6Kbyte of XRAM.

    Good luck!
    - mike

  • Servicing my non-running watchdog timer means that the code now works fine.

        while( !S0RIR )
        {
            _srvwdt_() ;
        }
    
        rx_char = ( uint8_t ) S0RBUF ;
        S0RIR = 0 ;
    
    Maybe a hardware problem ? Thanks for your help.

    Cheers


    Elliot

  • The watchdog timer is running unless you stop it before an EINIT or SRVWDT instruction.

    Sauli