infineon4engineers Facebook

infineon@google+ Google+

infineon@linkedin linkedin

infineon4engi@twitter twitter

infineon@youtube youtube

+ Reply to Thread
Results 1 to 9 of 9

Thread: Problem with frame finished interrupt of Usic Module in Uart mode

  1. #1
    Advanced Advanced Niclas has a spectacular aura about
    Join Date
    Jun 2015
    Posts
    87
    Points
    812.5

    Problem with frame finished interrupt of Usic Module in Uart mode

    Hi everybody,

    I'm working with a XMC4500 microcontroller in conjunction with Keil as IDE and debugger. I use 5 of the USIC-channels as UART-channels in half duplex configuration. Since my communication runs via RS485 I have a transceiver with a dedicated control pin to tell it to be in receive or transmit mode. Therefore I need to know exactly when a transmitted frame is finished in order to switch the RS485-transceiver back into receive mode.
    I used Dave 4.1.2 to configure the USIC-channels for UART communication and the Hardware-FIFO with 32 elements for each channel (16 for receive and 16 for transmit). Then I went ahead and modified the generated Dave-code of the Interrupt-service-routine for transmission (function name: void UART_lTransmitHandler(const UART_t * const handle)) in the file "uart.c".
    What the old Dave Code did was:
    - Interrupt gets called as soon as FIFO fill level goes to zero
    - see if there is more data to be send...if yes fill the FIFO again and finish the Interrupt Routine
    - if no data needs to be send anymore, wait in a while loop until the last byte has been copied into the shift register
    - set some variables and, if available, run the user callback-function

    What I didn't like was the while loop in the interrupt routine which waits for a whole byte to be transmitted in order to get to the user-callback-function. This function is then called while the last byte is still in transmission which is also not good for my application which, as mentioned above, needs to know exactly, when all the bytes have been send out.
    My modification of the code was supposed to do the following:
    - Interrupt gets called as soon as FIFO fill level goes to zero
    - see if there is more data to be send...if yes fill the FIFO again and finish the Interrupt routine
    - if no data needs to be send anymore disable the standard TxFifo event and activate the Frame Finished Event (during initialization I set the Interrupt Output line for the Frame finished Interrupt to the same line as the standard TxFifo event) then finish the Interrupt routine
    - Interrupt gets called as soon as the Byte before the last Byte has been finished...Interrupt Routine finishes doing nothing
    - Interrupt gets called again as soon as the last Byte has been finished...disable the Frame finished event and tell the RS485-transceiver to go into receive-mode and finish the Interrupt Routine.

    The standard TxFifo event is activated again as soon as new data has to be transmitted.
    Now, because this did not work I inserted a debug variable. I set this Variable to 1 at the beginning of the Interrupt function and I reset it to 0 at the end of the Interrupt function. Using a ULINKpro and the Logic Analyzer of the Keil Debugger I can see, that for each of the last two bytes where the Frame finished Interrupt is activated the Interrupt Routine gets called twice in short succession (~3 us). How can this behaviour be explained? I read the errata-sheet but there is nothing in there about this. Is this a hardware-bug?
    Just ask if more Information is needed.

    Best regards,
    Niclas

  2. #2
    chismo is on a distinguished road
    Join Date
    Apr 2013
    Posts
    267
    Points
    2451.25
    Hello Niclas,

    To understand better the problem, do you mean that switching off the transceiver after the second Transmitter Frame Finished interrupt is still too early?

    Regarding the duration between successive TFF interrupts, a shorter than expected duration could be the result of the late entry to the first TFF interrupt, e.g. if there is a same or higher priority interrupt being serviced when the first TFF interrupt is triggered.

    Regards,
    Min Wei

  3. #3
    Advanced Advanced Niclas has a spectacular aura about
    Join Date
    Jun 2015
    Posts
    87
    Points
    812.5
    Hi Min Wei,

    thank you for answering. I'll try to describe the behavior I see in the Debugger as best as I can...so to better understand you have to know that I modified the Dave-Code in the uart.c so that the FIFO is now filled in the "UART_Transmit" and not in the interrupt service Routine. So the FIFO is being filled and the standard TxFifo Event is activated.
    When the Interrupt Service Routine is called for the first time I know that the FIFO is empty. Two bytes are now still being send out, one in TBUF and one in the shift register. So in the interrupt function I deactivate the standard TxFifo event and activate the Frame finished Interrupt and after that I finish the interrupt function.
    Next time the Interrupt is called I know that the data in the shift register has been send and the data which was in the TBUF is copied to the shift register and send out. So being in the Interrupt function I just set a variable to remember that the next time I'm in the Interrupt function the last byte has been finished. So this call of the Interrupt is pretty quick. What I now expect is that it takes somwhere around 87us until the last Byte has been send and the Interrupt is called again (10 bits with a baudrate of 115200).
    [U]BUT[/U ] the next call of the Interrupt function is after around 3us!
    I went ahead and ignored this call. The next Interrupt then happens after the expected time of around 87us where I then deactivate the Frame finished Interrupt and tell the RS485-transceiver to go into receive mode by toggling a GPIO. Here, I noticed the following: when the deactivation of the Frame finished Interrupt happens too late the Interrupt Routine is called again after the mysterious 3us! When I deactivate the Frame finished Interrupt as soon as I get into the Interrupt function this second call doesn't happen.
    Also what I noticed with an oscilloscope is that the stop bit of the last byte is too short when I switch the RS485-transcevier back into recive mode (~6.5us instead of 8.6us with the given baudrate). When I do the switch of the transceiver in the second of the last two calls of the Interrupt function the length of the stop bit is ok.
    The measurement described above was done by using a global variable which I set to 1 at the beginning of the Interrupt function and to 0 at the end of the function. Using the logic analyzer in Keil's microvision with an ULINKpro as Debugger I can see the behaviour described above where I get two peaks of this debug-variable in short succession everytime the Frame finished Interrupt fires and as long as the Frame finished Interrupt isn't deactivated fast enough.
    I would've posted a picture of what I saw in the logic analyzer but I've already rewritten the code to the point where it now works reliable. If the description above isn't comprehensible I will go ahead and rewrite the code until I get the described behaviour again in order to post a Picture of the logic analyzer.

    Best regards,
    Niclas

  4. #4
    Advanced Advanced Niclas has a spectacular aura about
    Join Date
    Jun 2015
    Posts
    87
    Points
    812.5
    I reproduced the old code...this is what I see in the logic analyzer:

    LogicAnalyzerUartTransmission_0.bmp

    The variable "u8_DebugTransmissionStatus" is the variable I set to 1 at the beginning of the Interrupt. At the end of the function it will be set to 0 again.

  5. #5
    chismo is on a distinguished road
    Join Date
    Apr 2013
    Posts
    267
    Points
    2451.25
    Hello Niclas,

    From your description, I am suspecting that the transmit shift interrupt (TSIF) is also enabled.
    This interrupt is triggered with the shift of the last data bit so roughly one bit time earlier than TFF.

    Can you check this by reading out the CCR register? Specifically, bit 12 controls the TSIF interrupt generation.
    I doubt that the TFF event is triggering the additional interrupts.

    Regards,
    Min Wei

  6. #6
    Advanced Advanced Niclas has a spectacular aura about
    Join Date
    Jun 2015
    Posts
    87
    Points
    812.5
    Hi Min Wei,

    I went ahead and added some variables to the Interrupt function. Those Variables read out certain Registers at the beginning and the end of the Interrupt function. The Registers in the first measurements are CCR, TCSR and PSR and in the second measurement TCSR, PSR and PCR. The variables are also put into the logic analyzer. This is the result for CCR, TCSR and PSR:

    Click image for larger version

Name:	LogicAnalyzerUartTransmission_WithRegisterValues_CCR_TCSR_PSR.jpg
Views:	6
Size:	139.4 KB
ID:	1780

    In the Picture I added some numbered lines. These are the register-values at the corresponding line:
    Line 1:
    CCR = 0x00000002
    TCSR = 0x15000580
    PSR = 0x0000F583

    Line 2:
    CCR = 0x00000002
    TCSR = 0x15000580
    PSR = 0x0000F483

    Line 3:
    CCR = 0x00000002
    TCSR = 0x15000580
    PSR = 0x0000F483

    Line 4:
    CCR = 0x00000002
    TCSR = 0x15000580
    PSR = 0x0000F483

    Line 5:
    CCR = 0x00000002
    TCSR = 0x15000580
    PSR = 0x0000F583

    Line 6:
    CCR = 0x00000002
    TCSR = 0x15000580
    PSR = 0x0000F483

    Line 7:
    CCR = 0x00000002
    TCSR = 0x05000500
    PSR = 0x0000F483

    Line 8:
    CCR = 0x00000002
    TCSR = 0x05000500
    PSR = 0x0000F183

    And here the second measurement with the Registers TCSR, PSR and PCR:

    Click image for larger version

Name:	LogicAnalyzerUartTransmission_WithRegisterValues_PCR_TCSR_PSR.jpg
Views:	3
Size:	132.2 KB
ID:	1781

    Line 1:
    TCSR = 0x15000580
    PSR = 0x0000F583
    PCR = 0x00000901

    Line 2:
    TCSR = 0x15000580
    PSR = 0x0000F483
    PCR = 0x00000981

    Line 3:
    TCSR = 0x15000580
    PSR = 0x0000F483
    PCR = 0x00000981

    Line 4:
    TCSR = 0x15000580
    PSR = 0x0000F483
    PCR = 0x00000981

    Line 5:
    TCSR = 0x15000580
    PSR = 0x0000F583
    PCR = 0x00000981

    Line 6:
    TCSR = 0x15000580
    PSR = 0x0000F483
    PCR = 0x00000981

    Line 7:
    TCSR = 0x05000500
    PSR = 0x0000F483
    PCR = 0x00000981

    Line 8:
    TCSR = 0x05000500
    PSR = 0x0000F183
    PCR = 0x00000901

    I cannot see that it is TSIF that fires that one particular additional interrupt.

    Regards,
    Niclas

  7. #7
    Advanced Advanced Niclas has a spectacular aura about
    Join Date
    Jun 2015
    Posts
    87
    Points
    812.5
    Here some more Registers corresponding to the numbered lines in the Pictures above:

    Line 1:
    TRBSR = 0x00050901
    RBCTR = 0x14240000
    TBCTR = 0x44050100

    Line 2:
    TRBSR = 0x00050901
    RBCTR = 0x14240000
    TBCTR = 0x04050100

    Line 3:
    TRBSR = 0x00060901
    RBCTR = 0x14240000
    TBCTR = 0x04050100

    Line 4:
    TRBSR = 0x00060901
    RBCTR = 0x14240000
    TBCTR = 0x04050100

    Line 5:
    TRBSR = 0x00060901
    RBCTR = 0x14240000
    TBCTR = 0x04050100

    Line 6:
    TRBSR = 0x00060901
    RBCTR = 0x14240000
    TBCTR = 0x04050100

    Line 7:
    TRBSR = 0x00070901
    RBCTR = 0x14240000
    TBCTR = 0x04050100

    Line 8:
    TRBSR = 0x00000909
    RBCTR = 0x74240000
    TBCTR = 0x04050100

    One can see that the RxFifo gets filled during Transmission due to the half duplex nature of the UART-configuration. However, receive-interrupts are deactivated during transmission and the Interrupt Output-line is not the same line as for transmit-interrupts, so that shouldn't be the reason for the Problem.

    Regards,
    Niclas

  8. #8
    chismo is on a distinguished road
    Join Date
    Apr 2013
    Posts
    267
    Points
    2451.25
    Hello Niclas,

    Thanks for providing these details. It is clear to me now, the extra interrupt is due to the received frame finished event (RFF).
    RFF shares the same interrupt enable as TFF, i.e. PCR.FFIEN and with half-duplex UART configuration, data reception is taking place at the same time as data transmission.

    This can be seen from your observations on the PSR register.
    - The interrupt triggered at line 3 is due to RFF of the 2nd last received word. Hence at line 3 and line 4, RFF remains set and TFF is 0.
    - The interrupt triggered at line 5 is due to TFF as shown in PSR.TFF=1.
    - At line 6, PSR.TFF is cleared to 0 by your service routine.
    - The interrupt triggered at line 7 is then due to the RFF of the last received word. PSR.TFF remains 0 at this point in time.
    - But here do you clear PSR.RFF because at line 8, I see that PSR.TFF=1 but PSR.RFF=0.

    RFF is happening about half a bit time earlier than TFF. This because from receive perspective, the sampling points determines the completion whereas from transmit perspective, the completion is based on the end of the internal shift clock cycle.

    For your application, would it make sense to treat RFF as dummy interrupts and service only the interrupts triggered by TFF? In your service routine, you can check if PSR.TFF bit is set.

    Regards,
    Min Wei
    Last edited by chismo; Sep 29th, 2015 at 03:10 AM. Reason: Edited for typo

  9. #9
    Advanced Advanced Niclas has a spectacular aura about
    Join Date
    Jun 2015
    Posts
    87
    Points
    812.5
    Hi Min Wei,

    thank you very much! I didn't notice that receive and transmit share the same Frame finished Interrupt! Now that I know what the problem is I will find a solution that fits best. Maybe, as you said, by ignoring the Interrupt call or maybe by waiting until PSR.TFF is also set. Again, thank you!

    Regards,
    Niclas

+ Reply to Thread

Tags for this Thread

Disclaimer

All content and materials on this site are provided “as is“. Infineon makes no warranties or representations with regard to this content and these materials of any kind, whether express or implied, including without limitation, warranties or representations of merchantability, fitness for a particular purpose, title and non-infringement of any third party intellectual property right. No license, whether express or implied, is granted by Infineon. Use of the information on this site may require a license from a third party, or a license from Infineon.


Infineon accepts no liability for the content and materials on this site being accurate, complete or up- to-date or for the contents of external links. Infineon distances itself expressly from the contents of the linked pages, over the structure of which Infineon has no control.


Content on this site may contain or be subject to specific guidelines or limitations on use. All postings and use of the content on this site are subject to the Usage Terms of the site; third parties using this content agree to abide by any limitations or guidelines and to comply with the Usage Terms of this site. Infineon reserves the right to make corrections, deletions, modifications, enhancements, improvements and other changes to the content and materials, its products, programs and services at any time or to move or discontinue any content, products, programs, or services without notice.