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

C167CR S0-serial, PEC and 'transmitter buffer empty interrupt'

Hello,

I'm trying to write a serial port routine that uses the PEC unit for transmit and receive. Target processor is C167CR-LM.
I got this routines working when using the S0TINT interrupt service with PEC transfer, but not when using the S0TBINT.
I tracked down the problem to a single byte PEC transfer, where sometimes one expected interrupt is missing.
For a single byte PEC transfer I expect two interrupts:
- the PEC 1->0 transfer, that leaves S0TBIR set
- the 'real' transmitter buffer empty S0TBIR
Unfortunately, I often get only 1 of this interrupts.

Could this problem arise from the fact that the first byte written to S0TBUF is immediately moved to the transmit register and therefor the interrupts from the PEC and transmitter buffer empty come to the same time and can't be distinguished by the hardware?
This could explain why my routines work when using the S0TINT. Here the PEC 1->0 S0TIR is immediately active but the second S0TIR is rising after last bit of the transmitter is sent.

Is this a correct interpretation? Is there another way to check that the interrupt is caused by the TBUF-empty and not by the PEC 1->0 change?


- Heinz

Parents
  • Could this problem arise from the fact that the first byte written to S0TBUF is immediately moved to the transmit register and therefor the interrupts from the PEC and transmitter buffer empty come to the same time and can't be distinguished by the hardware?

    Yes, if you use PEC to send just one byte. This means that you trigger the transfer by setting the S0TBIR bit. PEC writes the byte to S0TBUF and leaves S0TBIR set. The byte is immediatelly transferred to the transmit shift register and the hardware sets the S0TBIR bit, which already was set.

    You could solve this by not using PEC for single byte transmits - just write the byte to S0TBUF and you know that you will get only one interrupt. Or you could consider the transmit not complete until you get a S0TIR interrupt after the S0TBIR interrupt. On the other hand you won't get any transfer rate improvement by using S0TBIR instead of S0TIR. The S0TIR bit is set at the beginning of the stop bit, which leaves one bit time for the PEC to write the next byte to S0TBUF before the transmitter goes idle. This is plenty of time for PEC.

    Sauli

Reply
  • Could this problem arise from the fact that the first byte written to S0TBUF is immediately moved to the transmit register and therefor the interrupts from the PEC and transmitter buffer empty come to the same time and can't be distinguished by the hardware?

    Yes, if you use PEC to send just one byte. This means that you trigger the transfer by setting the S0TBIR bit. PEC writes the byte to S0TBUF and leaves S0TBIR set. The byte is immediatelly transferred to the transmit shift register and the hardware sets the S0TBIR bit, which already was set.

    You could solve this by not using PEC for single byte transmits - just write the byte to S0TBUF and you know that you will get only one interrupt. Or you could consider the transmit not complete until you get a S0TIR interrupt after the S0TBIR interrupt. On the other hand you won't get any transfer rate improvement by using S0TBIR instead of S0TIR. The S0TIR bit is set at the beginning of the stop bit, which leaves one bit time for the PEC to write the next byte to S0TBUF before the transmitter goes idle. This is plenty of time for PEC.

    Sauli

Children
  • Yes, if you use PEC to send just one byte. This means that you trigger the transfer by setting the S0TBIR bit. PEC writes the byte to S0TBUF and leaves S0TBIR set. The byte is immediatelly transferred to the transmit shift register and the hardware sets the S0TBIR bit, which already was set.

    Ok, I already had this guess.

    You could solve this by not using PEC for single byte transmits - just write the byte to S0TBUF and you know that you will get only one interrupt. Or you could consider the transmit not complete until you get a S0TIR interrupt after the S0TBIR interrupt.

    The last solution makes things more complicated by taking case of two interrupt sources. Rewriting the transmit routine to send single bytes directly instead of using the PEC is IMO the better choice.

    On the other hand you won't get any transfer rate improvement by using S0TBIR instead of S0TIR. The S0TIR bit is set at the beginning of the stop bit, which leaves one bit time for the PEC to write the next byte to S0TBUF before the transmitter goes idle. This is plenty of time for PEC.

    That's true.

    BTW, I had another idea which failed also.
    The C167CR manual say:
    "A transmission is started by writing to the Transmit Buffer register S0TBUF
    ....
    After a transmission is completed, the transmit buffer register is cleared
    to 0000H"

    This seams not to be true! Reading S0TBUF reads back what was written last time!
    If it really where cleared I could have used the upper bits 9-15 as indicator by writing words where low byte is data to transmit and high byte is flag that gets cleared by hardware.
    I don't know any errata sheet mentioning this 'S0TBUF not cleared' error.


    - Heinz

  • Rewriting the transmit routine to send single bytes directly instead of using the PEC is IMO the better choice.

    Just for information:
    I got that version running now. Wasn't too much effort. Automatically switches to PEC transfer when more >= 2 chars have to be transmitted and back to direct transfer in the other case.

    - Heinz