infineon4engineers Facebook

infineon@google+ Google+

infineon@linkedin linkedin

infineon4engi@twitter twitter

infineon@youtube youtube

+ Reply to Thread
Results 1 to 3 of 3

Thread: Problem receiving bytes using UART interruption (losing some bytes)

  1. #1
    New Member New Member pedro_marinho_94 is on a distinguished road
    Join Date
    Apr 2019
    Posts
    2
    Points
    35

    Problem receiving bytes using UART interruption (losing some bytes)

    So everything was going fine with the UART application, I was using Interrupt mode for both reception and transmission.

    I'm working on a CAN application and I'm using a circular buffer. I need to receive bytes and transmit bytes one at a time through the serial port and I must use interruptions.

    Before I was using UART_Receive and UART_Transmit with FIFO enabled.

    When I started sending and receiving CAN messages with CAN_NODE the whole program got slower and I think it's because I needed to have the (UART_Receive == success) in the main loop so the program could enter the receive callback function so I could write the received byte to the circular buffer. The thing is this is not what is supposed to happen. I need to enter the receive callback function without having nothing in the main loop.

    I tried some solutions that are already here (creating my own interrupt routine with INTERRUPT app and assigning interrupt_std_receive) but RBUF is uint16_t and I need to read an uint8_t at each time.

    For example I'm supposed to receive something like "\r\nNORMAL POWER DOWN\r\n" and I'm receiving "\r\nRM W\r"


    volatile uint32_t receive_byte_count_ble = 0;
    uint8_t ReadData0_ble [3000] = {0};

    volatile uint32_t R_count_ble = 0;

    main(){
    while(1){
    }
    }

    void rx_callback(void){
    ReadData0_ble[receive_byte_count_ble]=XMC_UART_CH_GetReceivedData(UART_BLE.channel);
    receive_byte_count_ble++;
    }

    Any ideas? I just need to receive byte for byte and enter the callback function each time so I can save the byte to this array but bytes are missing.
    Last edited by pedro_marinho_94; Apr 15th, 2019 at 08:19 AM.

  2. #2
    Intermediate Intermediate ErnieT is on a distinguished road
    Join Date
    Feb 2018
    Location
    Germany
    Posts
    29
    Points
    570
    RBUF is probably 16 bits, because UART allows word sizes of more than 8 bits. See fields FLE and WLE (frame / word length) in register SCTR of USIC. Only the configured amount of bits will be present in RBUF register on receival.
    So maybe you are not losing data, because you are reading too much, but because some higher interrupt prevents you from accessing the interrupt often enough.

    Simply create a DAVE app with RX interrupt and access the RBUF inside to access your data. Example for USIC 1, interrupt 0 RX handler. If "rxOverflows" is non-zero, your RX routine isn't called in time.

    Code:
    uint32_t  rxOverflows;		/** Counts occurrences of lost RX data. Amount of lost RX bytes may be higher! */
    uint8_t   rxBuffer[128];	/** Circular buffer for incoming bytes. */
    uint32_t  rxPointer;		/** Points to next position to read into rxBuffer[]. */
    
    /**
     * Interrupt service routine for USIC 1.
     *
     * Receives incoming bytes.
     */
    void
    USIC1_0_IRQHandler() {
    
    	if (USIC1_CH1->PSR & (1U << USIC_CH_PSR_DLIF_Pos)) {
    		/* RX register shows data lost */
    		rxOverflows++;
    	}
    
    	/* add new character to your buffer */
    	rxBuffer[rxPointer++] = USIC1_CH1->RBUF;
    	
    	if (rxPointer >= 128) {
    		rxPointer = 0;
    	}
    	
    	// TODO: add check for rxBuffer overflow!
    }

    Live example can be found here: https://www.infineonforums.com/threa...ct-attached%29
    ATTENTION: No DAVE, just plain C code!
    Last edited by ErnieT; Apr 15th, 2019 at 11:15 PM.

  3. #3
    New Member New Member pedro_marinho_94 is on a distinguished road
    Join Date
    Apr 2019
    Posts
    2
    Points
    35
    Hello, I will try that when I can. Thank you very much.

    RBUF is 16 bits. There is also RBUF0 and RBUF1.

    When UART receives two bytes one after the other it fills RBUF0 first and RBUF1 after?

    I really just want the program to enter the rx_handler when it receives a byte so that I can save that byte to my buffer. That simple.

    Right now I just want a program that does only that (read byte for byte from the UART), no CAN interruptions no nothing. One step at a time. After I get this I will add the stuff I had before.

    MEGA EDIT:

    So I think I got it.

    What I did:

    Click image for larger version

Name:	Capturar.PNG
Views:	1
Size:	20.5 KB
ID:	3944

    I now for a fact that I'm receiving 86 characters and my rx_counter hits the number 86.

    Code:
    uint8_t   rxBuffer[128];
    uint32_t  rxPointer = 0;
    
    uint32_t rx_counter = 0;
    
    void UARTBLE_IRQHandler(void){
    	rxBuffer[rxPointer++]= USIC2_CH1->RBUF;
    	rx_counter++;
    }
    Did I got it? Is there a better way to do it?

    Click image for larger version

Name:	Sem Título.png
Views:	0
Size:	16.0 KB
ID:	3945

    Click image for larger version

Name:	Seatulo.png
Views:	0
Size:	21.3 KB
ID:	3946
    Last edited by pedro_marinho_94; Apr 16th, 2019 at 07:49 AM.

+ Reply to 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.